// < begin copyright >
// Copyright Ryan Marcus 2019
//
// This file is part of plr.
//
// plr is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// plr is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with plr.  If not, see <http://www.gnu.org/licenses/>.
//
// < end copyright >
#![allow(clippy::needless_return)]

//! This crate provides code for performing error-bounded piecewise linear
//! regression (PLR) in an online fashion using either a
//! [greedy](regression/struct.GreedyPLR.html) (constant time per point,
//! constant space) or [optimal](regression/struct.OptimalPLR.html) (linear
//! time per point, linear space) algorithm. Both algorithms were
//! implemented as described in:
//!
//! > Qing Xie, Chaoyi Pang, Xiaofang Zhou, Xiangliang Zhang, and Ke Deng.
//! > 2014. Maximum error-bounded Piecewise Linear Representation for
//! > online stream approximation. The VLDB Journal 23, 6 (December 2014),
//! > 915–937. DOI: <https://doi.org/10.1007/s00778-014-0355-0>
//!
//! Error-bounded piecewise linear regression is the task of taking a set
//! of datapoints and finding a piecewise linear function that approximates
//! each datapoint within a fixed bound. In other words, given a dataset
//! `(x, y) ∈ D`, we seek a piecewise linear function `f` such that `∀(x,
//! y)∈D(|f(x) - y| < δ)`, for some given δ. This can also be thought of as
//! minimizing the "L-infinity" loss. Since `f` could be trivially realized
//! by a piecewise linear function with `|D|` pieces, we also seek the `f`
//! with a minimal number of pieces.
//!
//! <div>
//! <img src="data:image/png;base64,
//! iVBORw0KGgoAAAANSUhEUgAABaAAAAFoCAYAAAChVFwCAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz
//! AAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjAsIGh0
//! dHA6Ly9tYXRwbG90bGliLm9yZy+17YcXAAAgAElEQVR4nOzdeVhU1f8H8PewCyqIiAsqCH5TQwUV
//! FUXFJdMUFff1Ky7h10pzrVxQ1NwqNZcyy7XUCkXCLTPLfaG0cMk9glTSXHBJRBb5/P7wN8QwKzAL
//! y/v1PPM8es+5935mmDn33s899xyFiAiIiIiIiIiIiIiIiIzMytIBEBEREREREREREVHJxAQ0ERER
//! EREREREREZkEE9BEREREREREREREZBJMQBMRERERERERERGRSTABTUREREREREREREQmwQQ0ERER
//! EREREREREZkEE9BEREREREREREREZBJMQBMRERERERERERGRSTABTUREREREREREREQmwQQ0ERER
//! EREREREREZkEE9BEREREREREREREZBJMQBMRERERERERERGRSTABTUREREREREREREQmwQQ0ERER
//! EREREREREZkEE9BEREREREREREREZBJMQBMRERERERERERGRSTABTUREREREREREREQmwQQ0ERER
//! EREREREREZkEE9BEREREREREREREZBJMQBMRERERERERERGRSTABTUREREREREREREQmwQQ0USmk
//! UCjQtm3bQm+nbdu2UCgUhQ8on5KSkqBQKDBs2DCjbM9Yn4e53bt3D66urnj99dctHUqJIiLw8/ND
//! 69atLR0KFROWagt1OXjwIBQKBWbNmmXpUKiUOHDgABQKBbZs2WLpUMjEYmJioFAo8OOPP1o6FItg
//! m09UMOvXr4dCocDPP/9s6VCoCOrevTt8fHyQkZFh6VDIRJiAJirCTp06heHDh8Pb2xtlypRB+fLl
//! 0aBBA7z11ltITk62dHiUi7GT4oaIjIxEWloaIiIizLZPXaKjozF27Fi0bt0a5cuXh0KhwJAhQ/Su
//! d/z4cXTp0gWurq4oU6YMGjZsiKVLl+LZs2da19m1axfatm0LZ2dnlC1bFs2bN8fnn3+ucz+ff/45
//! mjVrhrJly8LZ2Rlt27bFrl271OopFArMmTMHR48eRXR0tP43ThZjrjZy2LBhUCgUSEpKMto2ixpl
//! 8iL3y87ODtWrV0ffvn1x4sQJjfUNuXmnbB9zv2xsbODu7o7OnTtj+/btRn0vx44dQ2hoKKpWrQpb
//! W1uUK1cOtWvXxqhRo3D9+nWj7qsw0tLSEBkZiTp16sDBwQHu7u7o168fLl68mO9tPXv2DB9++CEa
//! NmyIMmXKwNXVFV26dMHx48c11ld+p7W9Ll26lK/9Z2dnY8KECfDz80Pfvn1zlmv622t6HTlyJN/v
//! mfJv1qxZUCgUOHjwYKG207NnTzRu3BgTJ05Edna2cYIzANt842Gbb36WbPMLsn/ljRZtr6dPn+Yr
//! 5sePH2PatGno1q0bmjVrlrM8NTUVmzdvxqBBg1C3bl04OTmhXLlyCAgIwOLFizUmI5OTk7FixQq8
//! 8sor8PLygr29PSpWrIiOHTsiJiYmX3FR4Xl5ecHLy6vQ25kzZw4SExOxfPnywgdFRZKNpQMgInUi
//! gilTpuD999+HjY0NOnbsiL59+yIjIwPHjx/HokWLsHLlSnz++efo06dPvrd/8eJFODo6FjrOL774
//! Ak+ePCn0dij/rl27hk8//RTDhw9HtWrVLB0OAGDu3Lk4c+YMypYti+rVqxuUwNi+fTt69+4NBwcH
//! 9O/fH66urti5cycmTJiAY8eOYevWrWrrfPTRRxg7diwqVqyIIUOGwM7ODtHR0Rg2bBjOnTuHRYsW
//! qa0zefJkLF68GNWrV0d4eDgyMjLw9ddfo1u3blixYgXGjBmjUr9Hjx6oV68epk+fjt69exe5nk6l
//! nanbyPwqSW2hp6dnzo201NRUxMXFITo6GjExMYiOjkbPnj0LvG1nZ2eMHz8eAJCeno7z589j165d
//! 2Lt3Lz744ANMnjy50PFfvnwZ7du3R3Z2NkJDQ1G7dm1YWVnh3r17OHnyJH799VfUqFGj0PsprPT0
//! dHTs2BHHjh1DQEAAxo0bh+vXr2Pr1q3YvXs39u/fj+bNmxu0LRHBgAEDEB0djTp16mDMmDFISUlB
//! VFQU2rRpg23btqFHjx4a1x03bhxcXFzUlru5ueXr/Xz99dc4c+YMNm/erNJeuri4IDIyUuM6169f
//! x7p161CxYkWVZAQVfQqFAu+88w769++Pr7/+GoMGDTLp/tjmmw7bfPOwdJtfmP1ra8NtbPKXSlq+
//! fDlu3bqFKVOmqCw/cuQIhgwZAldXV7Rr1w6hoaG4f/8+duzYgcmTJyMmJgY//vgjHBwcctZZsWIF
//! 3nvvPdSqVQvt2rVDlSpV8OeffyImJgY//PADJkyYgCVLluQrPrI8f39/dO7cGfPmzcPrr79ulHwF
//! FTFCREXO7NmzBYB4eXnJb7/9plYeHR0tDg4OYm1tLfv377dAhJaVmJgoACQsLMwo2wMgwcHBRSom
//! faZNmyYA5NixY2bZnyH2798vV65ckezsbDlw4IAAkMGDB2ut//DhQ6lUqZLY2dnJyZMnc5anpaVJ
//! ixYtBIB89dVXKuskJiaKvb29uLq6SmJiYs7ylJQU8fHxEQBy/PhxlXWOHTsmAMTHx0dSUlJUtuXq
//! 6ir29vYq21JauHChAJB9+/bl85MgUzN3GxkWFiYANH5PiirlbzAyMjJf9TW1hTNnzhQAUqtWLYPq
//! 56VsHz09PdXKvvrqKwEgjo6OkpqaalCsumzatEkAyKhRozSWZ2ZmFnofxjB//nwBIH369JFnz57l
//! LI+NjRUA8uKLL6os1+XLL78UANKyZUtJS0vLWf7zzz+LnZ2dVKpUSR49eqSyjrG/0y1btpTy5cvL
//! kydPDF5nypQpAkAmTJhglBhIv8jISAEgBw4cKPS20tLSxMXFRYKCggofmB5s8/Vjm882X1ebX5D9
//! BwcHi7HSRVlZWVKjRg154YUX1Mri4+Nl06ZNkp6errL80aNH0rhxYwEgixYtUinbtm2bHDx4UG1b
//! Fy5ckPLlywsAOXXqlFFiJ/08PT01/t4L4uuvvxYAsnr1aqNsj4oWJqCJipjExESxsbERW1tbOXv2
//! rNZ6n3zyiQCQOnXqqJwwrF+/XgDI+vXrZc+ePRIcHJxzIFbSdgL5119/ybBhw6RSpUri4OAgfn5+
//! smHDBq0ntZpOTHLXjY+Ply5duoizs7OUKVNG2rRpozFhmpycLLNnz5aWLVtK5cqVxdbWVqpWrSoD
//! Bw6U8+fPa/yM8pvsTU9Plzlz5oi3t7fY2dmJl5eXTJ8+XZ4+farx88hPTMoLOk2v9evX5+x/xYoV
//! 8sorr0jNmjXFzs5OKlSoIB06dJBvv/3W4PchIpKdnS1Vq1aVGjVqaCzPfeG0atUqqV+/vtjb24u7
//! u7uEh4fLgwcP8rW/gjAkAb127VoBIEOHDlUr+/HHHwWAtGnTRmX5jBkzBIDMnDnT4O3997//FQCy
//! bt06tXV0bS8pKUkAyIABA7S+BzI/Y7aRu3btkhYtWoijo6O4uLhI79695cqVKyrb0fbbzn2ira8t
//! PHnypHTq1EnKly8vLi4u0qtXL7l27ZqIiCQkJEj//v3Fzc1NHBwcpG3btnL69Gm193P58mV55513
//! pEmTJuLm5iZ2dnZSs2ZNCQ8Pl+vXr6vVN2Yy4u+//85537dv39ZbPy9dyYjs7GxxcnISACo3ogrq
//! xo0b4urqKra2tjJy5EiJjo6WW7duFXq7xpSdnS01a9YUAPLHH3+olbdu3VoAGJxI01VfW/tnzATb
//! xYsXBYAMGTLE4HUyMjKkSpUqAkAuXrxo8HoJCQkSHh4uPj4+4uDgIBUqVJD69evL//73P7l7965a
//! /S+//FLatm0rzs7OYm9vL3Xr1pV3331Xnj59qnH7mzZtkkaNGomDg4NUqlRJhgwZIsnJyWb5jYuI
//! pKamyvz588XPz08cHR3FyclJAgMD5csvv1Srm9/zLU9PT63tmdKtW7dk0qRJ8sILL4ijo6M4OzvL
//! Cy+8IGFhYZKQkKAWw7Bhw/L9N8wvtvls83Vhm69KU5tf0P0bMwG9Z88eASARERH5Wm/z5s0CQEJC
//! QgxeJzw8XGPSWpft27dL+/btpUqVKmJnZydVq1aVNm3ayMcff6xW9969ezJlyhSpW7euODg4SPny
//! 5aV9+/ayd+9ejdt+8OCBjBs3Tjw8PMTe3l7q1KkjixcvloSEBI3Xs8rj8x9//CErVqyQevXqib29
//! vXh6esq8efMkOztbRES2bNkiTZs2FUdHR6lUqZK88cYbWm8CX7x4UcLCwqR69epia2sr7u7uMnDg
//! QLl06ZJa3fxcRyrbBU2v3O/r8OHDEhISIh4eHmJnZyeVK1eW5s2by6xZs9T2n5aWJg4ODhIYGKjx
//! vVDxxjGgiYqY9evXIysrCz179kSDBg201nv11VdRtWpVXL58GYcOHVIrj46ORkhICMqVK4fRo0ej
//! f//+Ovd7+/ZttGjRAhs2bEC9evUwfvx4NGrUCK+//jqWLVuW7/dx6tQptGzZEk+fPsWrr76KkJAQ
//! HD16FB06dMDly5dV6h4+fBgLFy6Ei4sLevfujQkTJiAwMBDR0dFo1qwZzpw5k+/95yYi6NevH2bO
//! nAmFQoExY8YgJCQE69atQ79+/TSuk5+Y2rZti3HjxgEA/Pz8EBkZmfPy9/cHAKSkpGDcuHH4559/
//! 0LFjR0ycOBHdu3dHfHw8unTpgjVr1hj8fs6fP4+bN28iKChIZ723334bb7/9Nvz8/PDGG2/Aw8MD
//! q1evLtTjlMa0f/9+AEDnzp3Vytq0aQNHR0ccP34c6enpBq3zyiuvqNQpzDrA88dSPTw88MMPP0BE
//! DHpPZHrGaiNjYmIQGhqK6tWrY9y4cWjRogW2bduGwMBAlTYqMjISfn5+AJ4PV6D8bSsfK9bn5MmT
//! ORNahoeHo1mzZoiJicFLL72ES5cuoVmzZrhx4waGDh2Krl274tChQ+jYsSMeP36sFu+qVatQo0YN
//! DBw4EGPHjsWLL76INWvWoGnTpiadFyD399+Uw9HY2toWehseHh7Ytm0bnJ2dUbduXZw9exZ9+vRB
//! kyZNsG3bNiNEWXgJCQm4du0aXnjhBdSqVUutXFe7lNfTp09x/PhxODo6apw4Vd+29uzZg/feew+L
//! Fi1CbGwsHj16lJ+3AgD44YcfAACtWrUyeJ0dO3bg1q1baNOmDerWrWvQOjdv3kTTpk2xfv16+Pr6
//! 4s0338R///tf1KpVCxs3bsTNmzdV6o8YMQKDBg3C77//jt69e+ONN96Aq6srZsyYgc6dOyMrK0ul
//! /vvvv48hQ4YgKSkJYWFhGD58OM6fP4+goCA8ePBAa1zG+o0/ePAArVq1wrRp02BtbY0RI0YgLCwM
//! d+7cwaBBg7TO92Do+db48eMRHBwMAAgLC1M5VwGAJ0+eICgoCIsXL4anpydee+01jBw5Eg0aNMD2
//! 7dtx4cIFtX0rz0OU3wFTYJvPNl8Xtvn6t1XY/UdFRWHhwoVYsmQJ9uzZo3JebqiCHCeAf78j+Rnu
//! I7/rfPbZZ+jRowcuXLiAbt26YdKkSejSpQvS0tKwfv16lbp//vknmjRpgoULF6JSpUo519gXL15E
//! 586dsXr1apX6T58+Rfv27bFs2TK4u7tj3LhxaNu2LebNm4dJkybpjGvy5MmIjIxEs2bNMHr0aFhZ
//! WWH69OmYPXs2li9fjrCwMNSuXRujR49GlSpV8PHHH2PixIlq2/nuu+/QuHFjbN68GU2bNsX48ePR
//! oUMHxMTEoFmzZvj111817t+Q60gvLy9ERkbC2dkZzs7OKseV0NDQnP23bds257g0adIkhIaGwt7e
//! HitXrlTbr4ODA5o0aYKTJ0/i4cOHOj8jKoYsm/8morzat28vAOSzzz7TW3fQoEECQN59992cZcqe
//! HgqFQvbs2aNxPWjowTBixAgBIG+//bbK8tOnT4udnV2+e0AjV+9fpVWrVgkAee2111SW//3332qP
//! iin37eTkJJ07d1ZZnt8e0Mq754GBgSqPqt27d0+8vb01fh7Gjunp06cae6w8ePBAfH19pUKFCgY/
//! uqzs5aPtzr7yznWNGjXkzz//zFmemZmZ08vhp59+Ulnnm2++kcjISINfH374oc4YDekBHRAQoPMR
//! OV9fXwEgFy5cyFnm5uYmADT2dBORnF41ysc6Hz9+LACkbNmyGuvfuXNHAIi7u7vG8tDQUAGgsSc+
//! WYax2kgAsnPnTpX6S5cuFQDSvn17leX6eovqaws3bdqkUqZsbytUqCBz585VKZszZ44AkKVLl6os
//! v3HjhsZem3v37hUrKysZPXq0xv0bozec8kkBb29vg+rnpas33MaNGwWAVKpUSaV9LqgLFy6Iq6ur
//! 7N69W2X5F198IQqFQsaNG2fwttavX5+vdjHvMU+bXbt26ezRtXXrVgEg/fr107ut3377TQBI/fr1
//! NZafPHlSAEizZs1Uliu/03lf5cqVk48++sig96HUv39/nW25Ji+//LIAkM2bNxu8zvLlyzX+NkSe
//! t/W5j6HK33nPnj3Vjq3Kp5ZybychIUFsbGzEzc0tp6eqyPOegwMGDFDrKSxi/N+48m/y3nvvqSxP
//! S0uTTp06iUKhkPj4eI37N/R8S9cQHDt27BAAMn78eLWy9PR0redEAKRv375qZcbCNl8V23xVbPNV
//! aWrzC7p/5fc878vd3V22bt2qN9bcmjdvrvP8XZvOnTsLAFm1apVB9R8+fCiVK1cWhUKhcv2gS+PG
//! jcXOzk7+/vtvtbI7d+6o/D84OFgUCoXaEIH3798XPz8/cXBwUOmBr/x9DxgwIKfnsojItWvXcq5p
//! tPWA9vT0lBs3bqjso2LFiuLo6Chubm4q7+/p06dSr149tfeRkpIiLi4uUrFiRbVrmXPnzomTk5M0
//! atRI4/7zcx2pawiOXr16CQCNT3rk/XyVxo8fLwDUftdU/DEBTVTE1KtXTwBoTR7n9s4776hdYChP
//! tENDQ7Wul/cEMj09XcqUKSPOzs4aLzBeffXVfCegNY0JmJGRITY2NtKkSRO9702pW7duYm9vLxkZ
//! GTnL8puAfumllwTQ/Kia8vPKzxjQxogpt8WLFwsAOXTokEH1p06dqvPCXXnioGnsrHXr1gkAWbFi
//! hcZ1DH3pG+fLkAT0f/7zHwEgV69e1VjesmVLAVTHdLa1tRUAWsf0q1atmgCQv/76S0SeD6UCQDw8
//! PDTWz8jIEABiZ2ensXz06NEG/x7JPIzVRuZNOIg8H6NQOZZ4UlJSzvLCJCNatWqlVv/QoUMCPB/P
//! NCsrS6VMOfTLsGHD9L4/pQYNGqiM1Zl7//lNRnh6euZcXE+ePDnnYsPKykpiYmLU6ucnGeHs7Jyz
//! 7SlTpkhISIgoFAqxs7NT2XZhNG3aVPz9/TWWDRw4UADIL7/8YtC2tF18a3sZehxR3hTV1j5+//33
//! AkBefvllvdtSjnGvbRzeK1euCAC1cTfXrl0rUVFR8ueff0paWpokJCTIokWLpFy5cgJAPv30U4Pe
//! i4jkjNmfnJxsUP3ExERRKBRSsWJFrUNhaKJMQBsSm7+/v9jY2Mj9+/fVyrKysqRixYrStGnTnGXv
//! vvuuAJDZs2er1U9KShJra2uT/sbv3r0r1tbWEhAQoPH9KBO9b731ltr+83O+ZUgCeurUqRpj0OTW
//! rVsCQJo3b27wOvnFNl8d2/x/sc1XpanNL+j+lyxZIjt37pQbN25IWlqaXLp0SaZOnSp2dnZiZWWV
//! r3PjqlWriq2trcH1RURWrFghAMTf31/lmkub7Oxs6du3rwCQ119/3eD9NG7cWBwdHVXmidFE2Q73
//! 6dNHY7lyPO3cw3b4+PiIlZWVxrZk7ty5OhPQa9asUVtn+PDhAkBmzJihVjZr1iwBoDI2tvImm7Yb
//! y8pEb+7kdEGuIw1JQF++fFljuSbKeXg++eQTg9eh4iF/U5cSUbGRnxnlL1++jLS0NAQEBKBcuXJq
//! 5a1atcrXEBEAEBAQoLbM1tYWlStXxv3799XKdu/ejVWrVuHUqVO4e/eu2qOxd+/eRdWqVfMVg9Kv
//! v/4KKysrjY99tW3bVut6xo7p/Pnz+OCDD3D48GHcvHkTT58+VSk39HHKe/fuAQAqVKigs56mv4Fy
//! JvC8f4MNGzZgw4YNBu2/NHF1dQXw/G9NJYvyUfTcrK2t0apVKyQkJCA+Ph6enp6F3o+m32G1atUA
//! PJ/t29raWqXMw8MDAHDjxg2V5SKCzZs3Y8OGDThz5gzu37+PZ8+e5ZTb2dkVOlbg+eOls2fPBvD8
//! 8dVKlSqhV69emDRpElq2bFmobT98+DBn20r29vbYvn07OnXqVKhtA0B8fDxOnjyJ4cOHayzv2LEj
//! vvrqK+zcuRONGzfWu72DBw8WOqaiasSIESr/9/b2xqRJk1CnTh1069YN06dPx8iRI9W+n5oYekxS
//! Wr16NUQEYWFhsLe3Nzjm7t27Y9q0aXjjjTewd+9edOrUCUFBQXjxxRdVhgl48uQJzpw5Azc3Nyxd
//! ulTjtuzt7XHx4sWc/8fHxwPQ/Hi4p6cnatSogaSkJI3bMsZv/OTJk3j27BkUCgVmzZqltr3MzEwA
//! UIlZ1/51nW9pExwcDA8PDyxcuBC//vorunTpgqCgII3vQak4HSPZ5mvGNv9fJbnNL4gJEyao/L9O
//! nTqYP38+qlWrhrFjx2Lq1Kkah7fT5N69ewYfI4DnQ9CMHz8eVapUwbZt2wwarmXSpEnYunUrWrdu
//! jSVLlhi8r8GDB2PSpEl48cUXMWDAAAQHByMoKAiVKlVSqXfixAkAz7/XmtrpO3fuAPi3nX706BES
//! EhJQo0YNeHl5qdXXNxyJrrakSZMmamWa2hJlzGfOnNEY85UrV3JifvHFF/XuX9t1pC6DBw9GTEwM
//! mjdvjv79+6Ndu3YICgpC9erVta5TnI4tlD9MQBMVMVWqVMHFixdx/fp1vXWVdZQHo7zbMZRyfKXK
//! lStrLNe2XBcXFxeNy21sbFROoAFg2bJlGD9+PCpUqICOHTuiZs2acHR0hEKhQGxsLM6cOVOg8caU
//! Hj58CFdXV40nL9o+J2PHFBcXh/bt2yMrKwsdOnRA9+7dUb58eVhZWeH06dPYvn27wdsrU6YMAKgl
//! sPPS9DdQjoeW929gCc7OzgCgdXwv5fLc78PZ2Rl3797Fw4cPUbFiRa3rKLddkH3klpaWBuDfz5ws
//! z1htpLZ2TdkmGGvcOeV3MDfl71BXmTLhpDRx4kQsXboUVatWRadOneDh4ZHzvdywYQP+/PNPo8Qb
//! HBxssotwT0/PnCTeo0ePsG/fPrz66qvo168fTpw4oXbxk1+XLl0C8O+FS17KG4aGfHdMqbDtkqm2
//! BQAhISHw8PBAcnIyLly4oHPMXaXcxyR9bWVWVlbOmJqjRo0yKCYlT09P/Pzzz5g1axa+++47xMTE
//! AHh+QTx58mS8+eabAJ5fGIsI7ty5o5b80saQ8yBtCWhj/MaVSfyTJ0/i5MmTWuPMO04wkL/zLV3K
//! ly+PuLg4REZGYseOHdi7dy8AwM3NDa+//joiIiLUzqPMcYxkm882Xxu2+YZty9jHiVdffRUTJkzA
//! 6dOn8c8//2jsvJRXmTJl9F63KMXGxmLAgAFwd3fHgQMH4O3trXedt99+Gx9++CHatGmD3bt35+vm
//! 5sSJE+Hm5oaVK1di+fLlWLp0KRQKBYKDg/HBBx/kJGKV7fS+ffuwb98+rdtTttPKORUKen1tzGNL
//! 3rGptcWcm7GuI3v16oVdu3Zh8eLFWLduHT799FMAz5PoCxYsQMeOHdXW4fVXycUENFER06pVKxw4
//! cAA//PADwsPDtdZ79uxZzgmjpsno8jNpSPny5QEAf//9t8ZybcuNISsrC7NmzUKVKlXw66+/qvUo
//! Vt65LQxnZ2ekpKQgMzNT7eLp1q1bZolp7ty5SEtLw4EDB9R6XS9YsADbt283eFvu7u4A/j2pMIbY
//! 2FicPn3a4PouLi4GT8ijTZ06dXDq1ClcuXJF7U5+VlYWEhMTYWNjo3LiWadOHdy9exdXrlxBixYt
//! VNa5efMmUlNTUb16dTg6OgIAnJyccpIpN2/eVPtbXr16FQDwwgsvaIxR+RkrP3OyPGO1kdraNWWb
//! oOnk3lJu376N5cuXo379+jh+/Ljaxd5XX31locgKrnz58ujduzccHBwQEhKCoUOH4uTJk4Wa8MrB
//! wQEA8Ndff2ksVy43tOfghg0btCYdNfHy8sKwYcP01qtTpw6Af3se5aWvXcrNx8cH1tbW+OOPP5CV
//! laU26VJ+tqVUqVIlJCcnIzU11aD6uY9J+nq47dy5Ezdv3kRwcHDO55Af9erVQ1RUFLKysnDmzBn8
//! 8MMPWLFiBcaNGwcnJyeMHDky57fbqFEjrZMr5ZX7PMjX11et3JTnQcC/7c2ECRPy1XPP2KpXr461
//! a9dCRHDhwgXs378fH3/8MebMmYPs7Gy8++67KvXNcYxkm882Xxu2+Ya1+cbcP/D8cy9Xrhzu37+P
//! 1NRUgxLQ7u7uuHr1qsZrsdy2bt2KQYMGoUqVKti/fz/+85//6N32hAkTsHTpUrRr1w67du3KuQbI
//! j6FDh2Lo0KF48OABjh8/jm+++Qbr1q1Dp06dcOnSJVSqVCmnjVi2bFnODU9dLHl9raSM+cyZM2jY
//! sKHJ96dN165d0bVrV6SmpuKnn37Crl278MknnyAkJATx8fFqN6N4/VVyMQFNVMQMGzYM8+fPxzff
//! fIPz589rvBACgHXr1uGvv/5CnTp1ND5WmB9169ZFmTJlcPbsWY13so8ePVqo7ety9+5dPHjwAL16
//! 9VJLDj5+/Njgi0ddGjdujB9++AFHjx5Fu3btVMo09fooSEzKRyq13RH+/fff4erqqnHID02zteui
//! PIFQ9vwwhtjYWHz++ecG1/f09Cx0Arp9+/bYvHkzvvvuOwwcOFCl7PDhw3jy5AnatGmj0ouhffv2
//! OHbsGL777ju1BPSePXty6uTdz8aNG/Hdd9+pPaapbR2lS5cuwcrKyqBegGQexmojNf3unj17ltPe
//! NWrUKGe5vt+3qf3xxx/Izm97bc0AACAASURBVM7Gyy+/rNY+37hxA3/88YdF4jKGrl27onPnzvju
//! u+/w5ZdfYvDgwQXelvJ3evjwYWRkZKglHb7//nsA0PqdyWvDhg35ap+Dg4MNSkb4+PigZs2auHLl
//! ChITE1GrVi2Vcn3tUm4ODg5o2bIljhw5giNHjqgd4/KzLeB5T7hLly5BoVCoxaVNw4YNsW/fPly6
//! dAm1a9fWWfezzz4DkP/ez3nZ2NigSZMmaNKkCVq2bIk2bdogNjYWI0eORNmyZeHr64vz588jJSVF
//! a+/I3Bo1aoRvvvkGR48eVfus/vzzT5P3oGzWrBmsrKxw5MgRk+7H0LZMoVDA19cXvr6+CA0NRc2a
//! NREbG6uWgFaeh/j7+5smYLDNZ5uvHdt8w9p8Y+4feD504/3791GuXDm4ubkZtE7Dhg1x9epVXL58
//! GfXr19dYZ/PmzQgLC4OHh4dBPZ9FBGPGjMHKlSvRsWNHbN++vdA9Zl1cXNClSxd06dIF2dnZWLdu
//! HQ4fPozevXsjMDAQAHDkyBGDE9De3t5ISkpCUlKS2jAcpry+VgoMDMS2bdtw5MgRkyagra2tkZGR
//! obeek5MT2rdvj/bt26NChQqYOXMm9uzZo5aANsexhSzDytIBEJEqb29vTJs2DZmZmejevTsuXLig
//! Vic2Nhbjxo2DtbU1PvnkE1hZFe6nbGdnh/79++Phw4eYO3euStmZM2fwxRdfFGr7uri7u8PR0RG/
//! /PKLyuM/mZmZGDdunFHGflImHadPn67y+FdKSora+y1oTBUqVIBCocC1a9c0xuDl5YWUlBScPXtW
//! ZfnatWtzHnM1VOvWrWFtbY24uLh8rafLhg0bIM8npjXolZ8eItr06dMHbm5u+Prrr3Hq1Kmc5U+f
//! PkVERAQA4LXXXlNZZ/jw4bC3t8dHH32kEsP9+/cxf/58AMDo0aNV1lH+f968eSpjliUlJeHjjz+G
//! vb29xvED09PTcfr0aTRq1MjgxxLJ9IzVRu7fvx+7du1SWfbRRx8hISEB7dq1UxkLVDnci7bft6kp
//! L1qOHj2qkhB5/PgxwsPD1canL26USa3IyEi19+Ll5QWFQmFQm1O7dm20atUKycnJeP/991XKDh8+
//! jK1bt8LR0RH9+vUzKK6DBw/mq1009DF2hUKR0y69/fbbyM7Ozinbvn07jhw5ghdffFEtiXbt2jVc
//! unQJT548UVmubCcjIiJUjnEnT55EVFQUKlWqhN69e+csv3Xrltp4s8Dz79OwYcPw9OlTvPTSSwYP
//! v6W8sarvmPTnn3/i+++/R8WKFVXiMdQvv/yi8RFyZS+y3L3eJk6ciIyMDIwYMQIPHjxQW+f+/fsq
//! N5MHDRoEGxsbrFixQiXZLCKYOnWqyROR7u7uGDx4ME6dOoV3331X4/4SEhKQmJhYqP3oasvOnz+v
//! sUeeps9XSfk3z5sEMya2+WzztWGbb1ibX5D9JyYmIiUlRe293LlzJ+ececCAAWo9sLXRd5z4/PPP
//! MXToUNSsWROHDx82KPk8atQorFy5Eq+88gp27NhR4OTzgQMHICJqy2/fvg3g37YvICAArVu3RkxM
//! DNatW6dxW+fOnctZD3jeszo7OxtTp05V2cf169e1zlFgTMOHD4eLiwtmz56Nn3/+Wa08OzvbKEPw
//! VKxYEXfu3MkZOiO3w4cPa2yz9B1b3NzctN6soOKLPaCJiqBZs2YhNTUVS5YsgZ+fHzp16gRfX19k
//! Zmbi+PHj+Omnn1CmTBl89dVXRjvpX7hwIfbv34/3338fP/30E1q2bImbN29iy5Yt6NKlC2JjYwud
//! 6NbEysoKb775JhYuXIgGDRqgR48eyMjIwIEDB5CSkoJ27drhwIEDhdrHwIEDERUVhR07dqB+/fro
//! 0aMHMjMzER0djaZNmyIhIaHQMZUtWxbNmzfHkSNHMHjwYLzwwguwtrZG9+7d0bBhQ4wfPx579+5F
//! q1at0K9fPzg7O+PUqVM4evQo+vTpg+joaIPfj7OzMzp06ICDBw/i/v37+ZrUw5RiY2MRGxsL4N9H
//! Wk+cOJHTO8TNzQ2LFi3KqV++fHmsXr0affr0Qdu2bTFgwAC4urpix44duHz5Mvr06YP+/fur7KNW
//! rVr44IMP8OabbyIgIAD9+/eHnZ0doqOjcePGDUyaNEmtZ3TLli0xceJELFmyBA0bNkSfPn2QkZGB
//! qKgopKSkYMWKFRonBzl48CAyMjIKlCgh0zJGG9mtWzf07NkTPXv2RO3atXH69Gns2bMHrq6uWLly
//! pUrdDh064IMPPkB4eDh69+6NcuXKwcXFBWPGjDHH20WVKlUwYMAAfP311/D398fLL7+Mhw8fYt++
//! fXBwcIC/v3++htAxpkuXLmntAVazZk3MmTNH7zYCAgLQo0cPbN++HWvXrsX//ve/nDLlhbKhF7nr
//! 1q1D69atMWPGDBw4cADNmzfHtWvXsGXLFigUCqxZs0ZtYiFLmDhxInbt2oXo6Gg0b94cHTp0wLVr
//! 13ISJuvWrVM75g4dOhSHDh1SG8ppwIABiImJQXR0NBo1aoRu3brh3r17iIqKwrNnz7B69eqcR4GB
//! 53+zl156CS1atMALL7wAd3d3JCcnY9++fbh16xa8vb3zNfFw+/bt4eLigr1792q8qau0Zs0aZGdn
//! 53vyQaWNGzfi008/RatWreDj44MKFSogISEBO3fuhL29vcpTOSNGjMAvv/yClStXwsfHB506dULN
//! mjWRkpKCxMREHD58GMOHD8eqVasAPO8hOGfOHEybNg1+fn7o378/nJ2dsW/fPqSkpMDPz0/tBrKx
//! ffTRR7h69SpmzpyJjRs3olWrVqhcuTL++usvXLx4ESdPnsRXX31lcM90Tdq1awcrKytMnToVv/32
//! W875Q0REBPbt24e33npL5Xtx48YNbN++HVZWVnjrrbfUtvf999/DxcXF4J6TBcU2n22+Nmzz9bf5
//! Bdn/oUOHMHr0aLRq1Qre3t5wdXXFtWvX8O233+Lhw4cICAhQS/rr0qNHj5xroVdffVWl7MCBAxgx
//! YgSys7PRrl27nHkCcss79N+cOXOwZs0alClTBv7+/li4cKHaOv7+/ggNDdUbW8+ePVG2bFkEBgbC
//! y8sLIoIjR47g5MmTaNKkCV566aWcul9++SXat2+PkSNHYvny5WjevDlcXFxw48YNnD17Fr/99htO
//! nDiRM3TE22+/jdjYWHz99de4fPlyzm95y5YtOU/umOL6WqlixYqIjo5Gz549ERgYiA4dOsDX1xcK
//! hQLXr1/HiRMncO/ePYPH59amQ4cOOHnyJDp37pzz9Kqfnx+6deuGN998E8nJyQgKCoKXlxfs7Ozw
//! yy+/YP/+/fD09MSAAQNUtnX58mVcu3YNo0aNKtQQPVRECREVWT/99JMMHTpUvLy8xMHBQZycnMTX
//! 11cmTZok169f17jO+vXrBYCsX79e63YBSHBwsNryGzduyNChQ8XNzU0cHBzEz89PNmzYIFu3bhUA
//! 8uGHH6rUDw4OlrzNyIEDBwSAREZGaty3p6eneHp6qizLzMyUxYsXS7169cTBwUEqV64sQ4YMkaSk
//! JAkLCxMAkpiYmFM/MTFRAEhYWJjW95hXenq6zJ49W2rVqiV2dnbi6ekp06ZNk6dPn2r8PPIbk4jI
//! 1atXJSQkRFxdXUWhUKj9HXbu3CnNmzeXsmXLirOzs3Ts2FEOHTpk0N8sr9jYWAEgK1euVCvTFp+I
//! /r9PYURGRgoAra+8f3elo0ePyiuvvCIuLi7i4OAg9evXlyVLlkhWVpbWfe3YsUPatGkjZcuWFUdH
//! RwkICJANGzbojG/9+vUSEBAgjo6OUrZsWWnTpo3s3LlTa/2BAweKnZ2d/P333wa9fzK/wraRO3fu
//! lMDAQHF0dBRnZ2fp1auXXL58WeN6ixcvlrp164qdnZ3a9zm/baG+NkxTm5SamirTpk0THx8fsbe3
//! l+rVq8vrr78ud+/eLVBbnJeyvqZjg676ul5+fn4q71dbGyAicvr0aVEoFOLh4SFpaWkiIpKSkiJW
//! VlYSFBRkUExKN27ckNGjR0uNGjXE1tZWXF1dpVu3bnLs2LF8bcfUUlNTZcaMGVK7dm2xs7MTNzc3
//! 6dOnj5w/f15jfeXf+cCBA2plmZmZsmTJEqlfv744ODiIi4uLvPLKKxrf87Vr12TUqFHSqFEjcXNz
//! ExsbGylfvrw0bdpU5s6dK48ePcr3exk/frwAkAsXLmgsz8rKkmrVqgkAuXTpUr63LyISFxcno0eP
//! loYNG0qFChXEwcFBfHx8ZNiwYXLu3DmN6+zcuVO6du0qlSpVEltbW6lcubI0bdpUpk+fLhcvXlSr
//! /8UXX4i/v7/Y29uLm5ubDB48WJKTk8XX11ecnZ1V6hr7Ny7y/FxlxYoV0qJFCylfvrzY2dlJjRo1
//! pH379vLhhx/K3bt3Ddq/iObzLRGRjRs3ip+fnzg4OOT8VkVELly4IBMmTJAmTZqIm5tbzrlS7969
//! NX6PLl++LABk3LhxGvdvCmzz2eZrwjZfd5tfkP2fPXtWwsLCpH79+uLq6io2NjZSoUIFadWqlSxf
//! vlzS09Pz/f5DQ0PF3t5eUlJSVJYrf6P5uYZQXuvoehl6nfjJJ59IaGio1KpVS8qUKSMVKlQQf39/
//! ee+99zQeDx89eiTz5s2Txo0bi5OTkzg4OIiXl5d06dJFPv30U3n8+LFK/fv378vYsWOlatWqYmdn
//! J3Xq1JFFixbJTz/9pLEN1XUdp7zW0vSd0HU9mZiYKG+88YbUrl1b7O3tpVy5clKnTh0ZMmSIfPPN
//! NwbvX1s78/jxYxk9erR4eHiItbW1yucfFRUlAwYMkNq1a4uTk5OUK1dOfH19Zdq0aXL79m21fUyd
//! OlUASHx8vFoZFX8KEQ3PGxAR5TJ9+nTMnz8f3333HTp16mTpcAjPxyVs0KAB7OzsEB8fzzvERnb7
//! 9m14eXlh0KBB+eoJSEXfhg0bMHz4cKxfv96gsRvJcnbs2IEePXpg9+7d6NKli6XDIR0SExNRt25d
//! jB49GsuWLbN0OEb16NEjVK5cGf7+/kaZGLmkmDRpEj766CNcvHhR7+PylsQ2v/hgm1+yHT9+HEFB
//! QViyZAkmTJhg6XAsbvXq1Rg1ahRWrVql8hRAaZaeng5vb2/Uq1cPP/zwg6XDIRPgGNBElEPTLNLn
//! zp3D8uXL4erqWujJDsl4rK2tsWjRIpw5cwYxMTGWDqfEmT9/PqytrdUmXCIi8zl06BD8/f2ZiCgG
//! atWqhXHjxuGzzz5DcnKypcMpkDt37iAzM1NlWVZWFiZNmoSnT5+iZ8+eFoqs6Ll58yY++eQTjB07
//! tkgnn6l4YZtfsrVs2RJ9+/bFe++9pzaudUmm6fr62rVrePfdd2FjY4Nu3bpZIKqi6ZNPPsGtW7ew
//! ePFiS4dCJsIxoIkoR0BAAGrXro369evDyckJV69exe7du5GdnY1PP/0UDg4Olg6RcunSpQuWLVtW
//! 6HG7SJWIoGrVqti4cSOqVq1q6XCISi1egBQvERERcHJyQlJSEjw8PCwdTr5t27YNM2fOxEsvvYQa
//! NWogJSUFhw8fxpUrV+Dv74+xY8daOsQiIykpCe+88w7GjRtn6VCoBGGbX/ItWrQI69atQ2JiInx9
//! fS0djln07t0bmZmZaNKkCVxcXJCUlIRdu3bhyZMnWLBgAapVq2bpEIsMe3t7rF27Fn5+fpYOhUyE
//! Q3AQUY7Zs2cjNjYWSUlJ+Oeff+Di4oLAwEBMnjxZZfILIqLiio9jE5Em8fHxePfdd/Hzzz/j3r17
//! AJ737O7VqxfeeecdlCtXzsIRUkGwzSciS1q5ciU2btyIq1ev4uHDhyhbtiwaNWqEMWPGoFevXpYO
//! j8ismIAmIiIiIiIiIiIiIpPgGNBEREREREREREREZBIcA5pKFDc3N3h5eVk6DCKiIicpKQl37961
//! dBgWx+MEEZFmPE48x+MEEZFmPE5QYTABTSWKl5cXTp06ZekwiIiKnICAAEuHUCTwOEFEpBmPE8/x
//! OEFEpBmPE1QYHIKDiIiIiIiIiIiIiEyCCWgiIiIiIiIiIiIiMgkmoImIiIiIiIiIiIjIJJiAJiIi
//! IiIiIiIiIiKTYAKaiIiIiIiIiIiIiEyCCWgiIiIyqxs3bmDs2LFo0aIFHB0doVAokJSUZNC62dnZ
//! WLBgAby8vODg4AA/Pz9s27bNtAETERERERFRgTEBTUbHxAIREeny+++/Y8uWLahQoQJat26dr3Vn
//! zJiBWbNmYcyYMdizZw8CAwPRt29ffPvttyaKloiIzI3XE0RERCULE9BkdEwsEBGRLm3atMHff/+N
//! b7/9Fn379jV4vdu3b2PRokWYMmUKJk+ejHbt2uHTTz9Fu3btMGXKFBNGTERE5sTrCSIiopLFxtIB
//! UMmjTCwAwJo1a/D9998btF7exAIAtGvXDr///jumTJmCLl26mCxmIiIyHyurgt3/3rt3LzIyMjBk
//! yBCV5UOGDMGIESOQmJiIWrVqGSNEIiKyIF5PEBERlSxMQJPRMbFQfETEnsOmuGsG1w/yccXm8BYm
//! jIiISLvz58/D3t4etWvXVlnu6+sLALhw4QKPE0XB2S3Y/f0kLHMpi1s21qiS9QzjbKuga9gBS0dG
//! RMUEryeKn/VvH0HK9S+B7OsqyxVW1pj41XYLRUVEREUFE9BUZDCxYB6x8cl4a+tpZGbnf91jCSnw
//! mrIbADAksCbmhjYwcnRERNqlpKTAxcUFCoVCZbmrq2tOOVnI2S1A7BtAdgZ2Ozlilpsrnv5/Aumm
//! rQ2myB3Efh6A1WGnLBwoEZVkvJ4wry9nncD9W2kAgKcPt6olnwFAsp9hcf8QAExGExGVZkxAU5HB
//! xIJpxcYnY2LUaRQg76zRprhr+PKna1jSzx+hjTyMtFUiIuP77LPP8NlnnwEA7ty5Y+FoSpjPuwOJ
//! h1QWLavgkpN8zqFQIE6eInxvOFZ3Wm3GAImoNOH1hOld+ekW9q2/oF6gIfmcF5PRRESlFxPQVOwx
//! saDf4NUncCzB+Cfc2QKMjzqNjw9cxb6JbY2+fSKi3CpUqIAHDx5ARFSSC8qEgjLBkNeoUaMwatQo
//! AEBAQIDpAy3pcvV21uSWjbXm9RQKxN2Kw+4/dqOrd1cTBkhElD+8ntDv49f2A2K87TEZTURUujAB
//! TUUGEwvGFxufjPFRp02+n6u3U1Frym582J+9oYnIdHx9fZGeno6EhASVx6svXHjeE+vFF1+0VGgl
//! n56kc25Vsp7hpq32U8wZR2cwAU1EJsHrCeP7PSQEe6uNBxSK5y8j6e05EdaKf48VSW/vh9f77Y22
//! fSIiKloKNrsDkQnkTizkxsRCwUTEnjNL8llJ8Lw39ODVJ8y2TyIqXTp37gxbW1ts3rxZZfmmTZtQ
//! v359jutpCp93B2Y5AzHhBiWfAWDc/QeAaO8mlymZ2P3HbmNFSESUg9cTxnXRzx/73MMNSz5b1TB4
//! u8rks0KhyHlZK2xwbcoh/SsTEVGxxAQ0FRlMLBhPROw5bIq7ZpF9H0tIQcclBy2ybyIqPqKjoxEd
//! HY1ffvkFALBnzx5ER0fj0KF/Lz5tbGwwcuTInP+7u7tj4sSJWLBgAZYsWYKDBw/itddew/79+7Fg
//! wQKzv4cSa9fE50nnWc5q4zsbomvqEwSmpelMQs84OqMwERIRacTrCeO52LQZkJ6ObNuyBvV8dnDu
//! C8DJoG0rk8+5KRQKKESBG1OOFCRcIiIq4jgEB5lEdHQ0AKgkFipVqoRKlSohODgYwPPEQlhYGNau
//! XQtANbFQrlw5NG7cGFFRUdi/fz927NhhmTdSDBVmvOchgTUxN7SByrKOSw7i6u3UfG3n6u1UdFxy
//! kONCE5FWffv2Vfn/66+/DgAIDg7GwYMHAQDPnj3Ds2fPVOrNmzcPZcuWxbJly3Dr1i3UqVMHW7Zs
//! QUhIiFniLrF2TQROrTXa5lb/fRcNvLT3hsuUTMyNm4uIwAij7ZOIShZeT1jO5TbBwD//5Hs9hwr/
//! Q/rjHyCZZwu0X2VS+saUI6i+sHWBtkFEREUTE9BkEkwsWEZBks9BPq7YHN5Ca7kyiZzfXtVXb6ei
//! +bx9+Gl6x3zFQ0Slg+joHaurjrW1NSIiIhARwcRloeVjXOd8CxiJ/m6uiLocpbVK1OUoNHJvxPGg
//! iUgjXk9Yxu8hIci+fbtA69o6WOGNVfNz/n/xyAF8+9HiAm2LSWgiopJFIYZcARIVEwEBATh16pSl
//! w7CI/CaI/+PuVKAeyvlNclcuZ8ckNFERUJrbx9z4OeD5uM4FGFpDL2t7oMdHQMN+OYsafN5AxwqA
//! s50zjg48avxYiCjf2D4+V5o/h6Thw5F2Ik5l2cGWCzUPwyGSs+yNVfonD/xhzUqc2fctAKCf19tq
//! Q3BowyQ0UdFRmttHKjyOAU1UAuQn+awAsLS/f4GHx9gc3gJL+/sbXP/vfzI4JjQRkaUpJxMs4LjO
//! OgWMBGY9BGbcVkk+A0D/Ov11rvow46FxYyEiogK5OXu2WvIZANoenwKrzMfPE865XvWDPfDGqvYG
//! JZ8B4KVXX8ekqF2YFLULf1W+btCTUAA4JjQRUQnBITiIirnY+GSDk8/G6o0c2sgDoY08DB4f+urt
//! VAxefULnUB9ERGRkZ7cAMaMBPNNbNd8CRgIhS/RWiwiMwDdXv0GGjmE+OBY0EZFl3Zw9Gw+++lpr
//! edvjU1T+X+/SxULtr/nEwUiJvYoncbcMqs/hOIiIij/2gCYq5iZEnTao3n/cnYw+FMa+iW0R5ONq
//! UN1jCSmIjU826v6JiEizv1d0gsSEw6jJ51rBz3s6z3poUPJZaU7QHJ3lusaJJiIi03q4c6fO5HNe
//! hU0+K7mG/ge2PuUNrs+e0ERExRsT0ETFWPN5+2DIw2sFHe/ZEJvDW2BIYE2D6o43MFlOREQFd2L5
//! MLjfjYNho2vqYW0P9Fr9POkctqNAm+jq3RWONo4664TvDS/QtomIqHD+euttg+saK/msVDncD1bu
//! DgbXZxKaiKj4YgKaqJjquOQg/v5H+yPNSqZMPivNDW1gcBK6+bx9Jo2FiKg0i41PRtN729XmisqX
//! 3ElnDeM6F8TMFjN1lsfdisPuP3YXej9ERGS4i3XrGVzX2MlnpWoTmzIJTURUCjABTVQMRcSeM2js
//! ZXMkn5UMTUL//U8GBq8+YYaIiIhKn9k7z8Ma2QVbWcdkgoXV1bsr7KzsdNaZcXSGUfdJRETana9b
//! z6AnKQHTJZ+Vqk1sCpTTPD3Vt7a/YI39jyqvqFlrTBoPEREZHxPQRMWQIZMOVi5nZ7bks5KhSWiO
//! B01EZBr3n2TiWX5O7wo4rnNB6BsLOlMyMTdurkljICIiYGtnXygAg4ZqMnXyWan69BaAvWpE39r+
//! gr+sHiAn2P9/XZQb2LVrl1niIiIi42ACmqiYMWQIi/L21kafcNBQc0Mb4D/uTnrrTeR40ERERqW8
//! sbf5WXuIhm5tOYtyJ50LOK5zQXT17orAKoE660RdjuJQHEREJjQ3bi58k7KLVPJZqfrsVipJ6Jzk
//! c14K4NSpU+YLjIiICo0JaKJiJCL2nEHjPp+d3dkM0Wi3b2JblLe31lknG+BQHERERjT9m3MAgMis
//! Efji2UvIFkD+/5UtgEI5xIYZk855re60Wm+d2cdnmyESIqLSKepylEH1zJ18Vqo+uxWg+zIix+ef
//! f27aYIiIyGiYgCYqRgwZemNpf38zRKKfIUlwDsVBRGQcsfHJSM14lvP/yKwR8E7/ErX+/9XYaqvJ
//! h9gwVP86/XWWpz1LYy9oIiITCN8bblC9ah+8b+JIdKs+r7VB44MkJiaaPhgiIjIKJqCJiglDegsH
//! +bgitJGHGaIxjCHjQY/nUBxERIWm7P2szazuvmaKRL+IwAi9ExKyFzQRkfHF3YoDAJzxhMYJCAWA
//! y8ABcO7WzaxxaVJ9QWtUg4vmQHNZsGCBeQIiIqJCYQKaqBiIjU/GsYQUnXUql7PD5vAWZorIMIaO
//! B82hOIiICi5v7+e8ythaFambk4D+CQnZC5qIyLgCvgjI+ff8QTY5SWjlK8Ma+Pa/L6BqZKSlQlQz
//! avZ4vT2h09PTcfbsWfMEREREBcYENFExMHGL/l7Clpp0UJ99E9vCxkr3mSOH4iAiKjh9vZ8X9Gpo
//! pkgM19W7KxxtHHXWmXF0hpmiISIq2ebGzUW6pKssmz/IBv2n/vsa8rYNJk/fbqEItQsICNBbJyYm
//! xgyREBFRYTABTVTEdVxyENl6Hj0zZKgLS1rU109vnYkcioOIKN+KY+9npZktZuosz5RMzI2ba6Zo
//! iIhKLkMmHtQ3Pr+lhISEwNpa/6yEnJCQiKhoYwKaqAiLjU/G1dupOutY4flQF0VZaCMPvUNxZAOI
//! iNXdi4+IiFQVx97PSob0gjYkaUJERNqFfhOqt469wh4RgRFmiKZgZszQ/0QMJyQkIiramIAmKsL0
//! JRYAYEl/fzNEUnj7JraFnpE4sCnumnmCISIqAYpz72clfb2gAbAXNBFRISQ8StBb59TQU2aIpHDc
//! 3Nz01uGEhERERRcT0ERFlL7EAgAE+bgW+eRCbkv66U+Wc0JCIiLDzN55Xmd5Ue79rNTVu6vex77Z
//! C5qIqGBabm6pt45PeR8zRFJ4Y8aM0VuHExISERVdTEATFVGTt57RW2dzeAszRGI8oY08EOTjqrMO
//! JyQkIjLM/SeZWsuKQ+9npYjACNhZ2emsw17QRET5s/uP3fgn6x+99WJ7xpohGuPghIRERMUXE9BE
//! RVBE7Dlk6Zl5cGkxGXojL0OS5lNj2HOBiKgwikPv59zmBM3RWR51OQq7/9htpmiIiIq/KUem6K2z
//! sPVCM0RiPCEhIQbV44SERERFDxPQREWQvrGQi1PPNk2GBNbUWZ6Wmc1e0EREOuhrI4vbMaKrd1e9
//! vaBnH59tpmiIiIq38L3heuuUsymHrt5dzRCNcfXq1UtvHU5ISERU9DABTVTEGDIGcnHr2ZbX3NAG
//! sNEzI+FbW0+bKRoiSJH7IwAAIABJREFUouLHkElqixt9vaDTnqWxFzQRkQHibsXprXN88HEzRGJ8
//! DRs2RNmyZfXWW7RokRmiISIiQzEBTVSExMYn41hCis46xW3iQW0W9fXTWZ6Zrb+HHxFRaaRvkloP
//! lzJmjMZ4unp3haONo8467AVNRKRbh6gOeusUl4kHtZk8ebLeOo8fP+aEhERERQgT0ERFiCE92orb
//! xIPahDbygJOdtc467AVNRKRO37HirU51zBSJ8c1sMVNnOXtBExFpt/uP3bj99LbeesVp4kFtOCEh
//! EVHxwgQ0URGhr0cboH/s5OJmXs8GOsvZC5qISJW+Y0VxnyPAkF7QM47OMFM0RETFiyETD/av098M
//! kZieoRMS7tq1y8SREBGRIZiAJioi9PVos8LzsZNLktBGHrC30d0MTYxiL2giIiV9x4riPkcAoL8X
//! dKZkYm7cXDNFQ0RUPBjaLkYERpg4EvPRNCGht08cglptQqvWGxHUahNS7n9kgciIiCgvJqCJigh9
//! vZ+X9Pc3UyTm9V5v3cmSbAARsSVvsi0iovwq6b2flQzpBR11OcpM0RARFQ+GtIsLWy80QyTmk3dC
//! Qm+fOFSrdhVWVgKFArCyElSrdhV79w61YJRERAQwAU1UJAxefUJneUlJKmgS2sgDQT6uOutsirtm
//! pmiIiIqu0tD7WUlfL2gACN8bboZIiIiKgV0TARGdVdwd3NHVu6uZAjKf3BMSVq16FQqFarlCAVhZ
//! HzNzVERElBcT0EQWFhufjGMJKTrrlKSkgiaGTKzIsaCJqDQrLb2flbp6d9U7TmncrThOSEhEBACn
//! 1uqt8mP/H80QiGXUqlULANSSz0oKBXDxkv4bm0REZDpMQBNZmL4ebbZWKFFJBW30TbD41laOBU1E
//! pdfsned1lpfEG5URgRGws7LTWYcTEhJRqXd2i+5yEQRWCTRPLBYSFhams1yhAP76a7OZoiEiIk2Y
//! gCayIH092gDgg74lc+znvPRNsJiZzV7QRFR63X+SqbWspPV+zm1O0Byd5ZmSyV7QRFS6bR8DAHDP
//! ylIfhkME1iJY3Wm1BQIzr4CAAL11bt7aboZIiIhIEyagiSyIvZ9VVXC01Vk+NeasmSIhIio69N18
//! K4m9n5W6enfV23OPvaCpNEuNv42bC3/GjSlHcHPhz0iNv23pkMjcnqUDAH68cfPfJPT/v9yzsnC6
//! SaSFAzSPkJAQADY661y48I55giEiIjVMQBNZEHs/q4rs5quzPC0z20yREBEVHR/svayzvKTfqNTX
//! cy9TMjE3bq6ZoiEqOlLjb+NBzFU8e/A8AfnsQToexFxlEro0+ai5yn9/vHET55Ku57x+vHETaNjP
//! QsGZn6/v+3pqaH+aiIiITIsJaCILiYjV3fu5JD9SrU1oIw8E+bjqrDN49QkzRUNUdETEnoPP1G/h
//! NWU3fKZ+q7f9oJIl+UGa1jKXMrqfHCkp9E1IGHU5ikNxUKnzcGcCJM/NecnMxqO9SZYJiMzv7iXd
//! 5QEjzRNHEVG1Sg+9dX759b9miISoiPioOTDL+d9XnptWRObEBDSRhWyKu6azvCQ/Uq3L5vAWOsuP
//! JaRwLGgqVQavPoFNcdfw7P/HdXwmgk1x15iELiX0tXezuut+cqSkiAiM0FtnwU8LzBAJUdGQGn8b
//! 2U+yNJYpe0RTCbdrov46IUtMH0cR4+LSUmf5gwfHzRQJkYUtqqt+k+ruJSahyWKYgCayAH2Jo9I2
//! 9nNeTnbWOss5FjSVFrHxyTiWkKKx7Kufrps5GrIEfXMFlKZjhb5e0A8zHpopEiLLe7gzQWuZtYu9
//! GSMhizm1Vnd5rWDzxFHENGm8UW+di5dmmiESIgs6uwV4fFNzmb4nJ4hMhAloIgvYrKf3c2kb+zmv
//! eT0b6CxPy8xmL2gqFd7Zpv1my7O8M91TiRMbn6xzrgAPlzJmjMbyIgIjYGdlp7MOx4Km0kJb72cA
//! KN/Jy3yBkGUY0vs5bIfp4yii9PWC/uuvzWaKhMhCYkZZOgIiNUxAE5lZbHwydKWNSnvvZ+D5+7e3
//! 0d08zdpx3kzREFlGbHwy0rO0T7xprVCYMRqyBH29n9/qVMdMkRQdc4Lm6CyPuhxlpkiILEffJINO
//! jdzNFAlZjL7ez3pu1pV0hvSCvnlruxkiIbIUdlShoocJaCIz05dQKO29n5Xe6617DOwHaZzFmko2
//! fW3FwOY1zBQJWYK+3s+lcaJaAOjq3RWONo4664TvDTdTNESW8eCbq1rLFGV0D2NGpUTox5aOwOIU
//! Chud5RcuGNCLnKg44hjPVEQxAU1kRvoSCgB7PyuFNvLQOxY0h+GgkkxfWzE3VPdQNVS8zd6p+ymP
//! 0jpRLQDMbKF77M64W3HY/cduM0VDZF6p8bchGdqfjnHpXtuM0ZBFfN5df52G/UwfRxFXr977euuw
//! FzSVSPrGeC5b1TxxEOXBBDSRGenr0ehSxtZMkRQP+saCfmvraTNFQmRe+iYqHRJY00yRkKXcf6L9
//! KY/S2vtZqat3V71jQc84OsNM0RCZl67JBwEOv1EqJB7SXR4w0jxxFHFVq/TQW+fChXfMEAmRGRly
//! g2oyJyEky2ACmshMDOn9PKu7r5miKR5CG3lA1yi3mdnsBU0lk76JStn7uWTT166V5t7PSvrGgs6U
//! TPaCphInNf62zskHOfxGKWBIcilkienjKCaqVRuspwaH9KMSRt8NKiILYgKayEz0PU5d2nu0aTNY
//! T09P9oKmkkbfRKVlbHnoLun0PS3DY8XzXtCBVQJ11mEvaCpp9PV+5vAbpYC+5FKtYPPEUUzUq6v7
//! ZiUA/PLrf80QCVERwSckyIJ4FUtkJroepwbYo00bfT092QuaSpp3tp3VWc62omTT97QMh2r61+pO
//! q3WWZ0om5sbNNVM0RKanq/ezY2AVDr9R0u0yYNK8sP9j797DoyrP9Y/fkwOYgJCwFTmoBVEBERRN
//! f41Si2CpVgxEVFDB07Zqre5WqYiUVEBBt/VEWw8VdCsqVqBIQOqWraJWrbib3QgKQamAIAfRhniA
//! EJLM/P6gnDPvO0nWYdZa38915bp03pXwOMFZM8961v0ucL+OgLFNQVdV/dWjSgCX3Z1CRB93SMBH
//! NKABD9gapEw/m9nybicuME+XA0FRWr5BNXXJN5fKzmD6Nexs089ENe1vRPcRxvVZH80iigOhsK18
//! i3G9XfFxHlUC35Q9YV63ZONHVSpT0BUrzZvbAoFQ85V5nTsk4DMa0IAHbA0FJhrNbFPQVdXktyEc
//! bK8V9150skeVwA+26WcuVh6spLDEesykv07yoBLAXab4DbKfI2DZbPsxxQ+7X0dA5eSYL9Bs3DjT
//! o0oAl9zXw34Md0jAZzSgAZelsvkgDQU72xQ0MRwIA14ros22VwAXKxtmm4Kurq9mChqBZ4rfIPs5
//! AubfaDkgU+oz3JNSguj00162HrNp83wPKgFc8u0m83rrjt7UARjQgAZcZptotDVWsYttCprNCBF0
//! JaW8VkSdaa8App+TKyksUQvLredsSIggs8VvkP0cAfU15vVhf/CmjgCLxVoa11esGOtRJYDDZgyx
//! H3PLSvfrACxoQAMuSmX62dZYxV4ZseRrbEaIoJu5ZJ1xPWyvFevXr9eFF16otm3bqk2bNho2bJjW
//! rTM/B7vFYrEGv95/P7gXomyvX0w/m93Rz5zxyYaECDLiNyIuleYS089WPXvebTmCSD8E1Jo3/a4A
//! SAkNaLiCxsIuttup83KyPaokHC79nnkCdNwLyzyqBHBWafkGJQzrOdnhOl1v375dAwcO1MqVKzVj
//! xgw988wzWrVqlQYMGKBt27al9DOuvPJKvfvuu/t9HX/88S5X7h7T3TJMP9sNPmawcrNyjcfM+miW
//! R9UAzopi/AafJfZhay6xsVhKOnYYaj3mr++e40ElgINSyYcfNt39OoAUZPldAMJnd2OhZcuWmjFj
//! hmKxmEpKSjRgwAAtW7ZMrVq1sv6MK6+8Utddd91+jwWxsWC6nVqSJg7p5VEl4TC5uLeeNUyJVtfG
//! VVq+gUYNAmfsXPPFk7BNv06fPl2rV6/WRx99pGOP3dU86dOnj4477jg99thjGj16tPVndO7cWYWF
//! hW6X6gnb3TJh+/275fbTbtdtb91mPGbykskpbVwIpIsoxm/wWWIfC+3nQzYWS12nTiONGw5WV6/y
//! sBrAAS9caz+GOySQJmhAw3E0Fnax3U7NRFvTjCo82tiEnrhgOc8rAqW0fINq6uJJ17Mzwrf54IIF
//! C1RYWLjnHCFJXbt2Vb9+/TR//vyUzhNhYrtbJmy/f7cMPmawyreUGyedZ300iwY0AiWK8Rt8lthH
//! 2RPmdaafG6VnjzuMDWhJqlh5u3r2MMc6AekioYQMKZW8RiCthOueXqQFW2MhKmwNBSbamsaWg1tV
//! TX4bgsX2WnHvRSd7VIl3li9frhNPPPGgx3v16qUVK1ak9DMeffRRtWzZUrm5uRo4cKDeeustp8v0
//! jOluGaKaGieVDQnJgkaQRDF+g88S/5LKrfVMPzdaXt7pxnVbgxpIFyWlH8iY4SfxGoG0QgMajqOx
//! sIstfoOJtqbLzzU3ZNiMEEESxdeKyspK5efnH/R4u3bttHXrVuv3jxo1So888oheffVVTZs2Tf/8
//! 5z81cOBAvfHGGy5U6y7b6xVRTY1n25Bw1kez9OfVf/aoGqDpohi/IfFZYo/S6y0HhHMC3m2nnvKM
//! 9ZiKlbd7UAnQPKa7ghMJSa07elcMkAIa0HAcjYV/XY00YKKteSYUmRsyExeYJ0qBdGFrPo4qNG+8
//! GVXPPPOMRowYoTPOOEOjRo3S22+/rU6dOqmkpOFohWnTpqmgoEAFBQX64osvPK7WzLT5oBTOCxBu
//! G3zMYOsU9KS/TvKoGqDpohi/IfFZYo948ul3SdKwP3hTRwjFYi2N60xBI92lNHB1y0r3CwEagQY0
//! 0k4YGgszDVcjJSbamsvWkCGGA0Fhaz7aImeCKj8/v8EmQrKmg82hhx6qwYMH629/+1uD69dee63K
//! yspUVlamww8/vNE/3y22zQe5WNl0tino6vpqpqCR9qIYv+GExn6WkNLw88SMIfZj2FisyXr2vHu/
//! f39H39cv9KhGao5+oUf1jr7vU2VAanZ/hngr3mvXtPM+EglpVesCH6oCzGhAw3FRbyyUlm8wRjGx
//! +aAzbDEctil0wG+25qNxQ5GA69Wrl5YvP/hOhRUrVuiEE05o8s+NxYL1rNkuQHCxsukGHzNYuVm5
//! xmOYgkY6qyxdZVwPa/yG5P1nCSn9Pk8k1rxpPqDgam8KCamOHYbu+ed39H09phv0Zay9FMvQl7H2
//! ekw36L4lU3ysEDDb/Rni8trxe5rQu7/eivfS8WNe87lC4GA0oOG4qDcWbA0FNh90hi2Gw5SJBaQD
//! 2+aDI0McvzFkyBAtWbJEq1ev3vPY2rVr9c4772jIkBSmvg7w9ddfa+HChfp//+//OVmmq2wXILhY
//! 2Xy3n2bO8GQKGulqW/kWbV+yOel6mOM3JD5LzP6v++0bi533gCe1hFmnTiMlSU/r31Uf2z+2qT7W
//! Qr/fPsCPsgCrAwetLq8dr641z+35urp+vE+VAWY0oOG4qDcWTA2F7AzyPJ1S3LezWrUwfwBjM0Kk
//! M9vmg2GN35Cka665Rl26dNHQoUM1f/58LViwQEOHDtVRRx2l6667bs9xn376qbKysnTHHXvjFO67
//! 7z5dc801eu655/TGG29oxowZ6tevnzZv3qwpU4IzrcTFSvelMgX967d/7VE1QOq+XrTWuB72+I2o
//! f5Y4fe0jMvbKu/b3rJYw69lj13uLb9WmwfUa5Wju5kovSwJSYov7vPeikz2qBGgcGtBwXJQbC7aG
//! JycDZ00539ygG/fCMo8qARon6huVtmrVSosXL9bxxx+vyy67TCNHjlTXrl21ePFitW7des9xiURC
//! 9fX1isfjex7r3r27VqxYoZ///OcaNGiQRo8era5du+rtt9/WGWec4cd/TqMx/ewd2xR0baJWk5dM
//! 9qgaIDX1VTVJ12I5maGO35Ci/VlCkjrFvjQfcMUCbwqJgLy805MvxmIq+fgz74oBUmS7QYL3kEhX
//! WX4XgPDZ3Vi4+eabddlllymRSOiss87S1KlTU2oszJs3T/PmzdNXX32lNm3aqF+/fnriiScCMbUw
//! dq654cnJwFnFfTtr7NxlqqmLN7heXdvw44DfnnuPjUqPPvpozZ0713hMly5dlDhgZ5WioiIVFRW5
//! WZrrbPErTD87Z/Axg3XHu3doe932pMfM+XiOSgqTb04GeGlb+Rbjetinn6Vof5YoKf1AP00cpiOT
//! NaEzWjT8OJrk1FOekRaXJ13fWs9nCaQX2xDLqBBH+CH4aEDDFVFsLJSWb0jaCJV2TbTBefdc0Ec3
//! zXo/6Xpp+QYa/0g7ccPoAtOv4WeKX+H377zbT7tdt711W9L1eIIGA9KHLX4j7NPPu0Xxs4S0aw+T
//! rzOG697sx9Qytv+dMvGElFH8sE+VhVdeVlxV9clj/cZ+tE73dKeph/Rgi98Ic4Qfgo+OGOAQ8jz9
//! YWvUjJmTvDkN+ME2ucBrRbjZopr4/Ttv8DGDNaL7CElSv+X1evjhOj1/d50efrhO/ZbXKyPG22Gk
//! D1P8RmZeSw8rgdd2nx8WxL+vMbXX6Z/x1kokpERCqky01q2JG6U+w32uMnymHN9VplCDpzeSA430
//! YYvfANIZE9CAA2x5nhLxG25q1SIz6fNfG2cKGunFNrnA39VwM8VvMP3snpLCEh3y2t901ksf65C6
//! XY8d/rV03UsJFXYo8Lc44F9s8Rttzu7iTSHwxb7nhwXx72vBzu/vtz51BHvJuOGCDu10Y8W6pI09
//! Gn5IFyOnv2tcJ34D6Y6RD8ABtjxPTgbusm1GOHGB+fcDeKW0fIPxg0zYNx+EOX6D6Wd3DX3t2z3N
//! 590OqZMKZ6/wpyDgAF+9+IlxPSrxG1FlOj9IXKB20+Wd2hnXx35kHh4AvPDOJ+ZpfOI3kO5oQAMO
//! sL1h5GTgruK+nRUzrFdVm38/gFdsF6uisPlglNniN2guuKtu06YGH09UVemrF1/0uBrgYPHtdUnX
//! iN8IN9v5gb1k3GXLeJ5BDAd8ZovwA4KAMxngMiYavTHSMmVue2MPeMF0sSo7gwZk2Nn2CoC7sjp2
//! TLq2acpdHlYCHIz4jWhjLxn/2RojczfThIZ/bBF+3HGNIKABDTST7WokE43esE2ZE8MBv9kugtx7
//! EdmOYWbbK4CLle5rf/NNSdcSVVUeVgIczBi/kR0jfiPk2EvGf5dZYjjGrCSGA/6xZZFzxzWCgAY0
//! 0ExsKBYMxHDAb7b4DV4rws023cbFSve1LSoyrhPDAT+Z4jfyhx3vYSXwGvEb6cEWw7Gd3QjhE9vA
//! G9PPCArOZkAzsKFYesnPNT/fZGfBT6b4DVOGOYLPNv2ck53BBQiPZOblJV0jhgN+qSxdZVxn+jnc
//! iN9IH/lZmcZ1YjjgB9vAG9PPCAoa0EAzsKFYeplQZH6+n7WcvAG32C5+2DLMEWw0F9LHEeN/lXSN
//! GA74YVv5Fm1fsjnpeizH3BBD8BG/kT4mH2d+rks+/syjSoC9GL5HWNCABpqBDcXSS3HfzmrVwvxB
//! jc0I4QcmF6KL6ef0QgwH0s3Xi9Ya1/OGHOtNIfCF7X0pd1N664IO5hzorfVxjyoBdiF+A2FCAxpo
//! IjYUS09TzmczQqQXonqizXanDNPP3iOGA+mkvqom6VosJ5P4jZAbO3eZcZ27Kb1ni+EY+xF3VMI7
//! tjt4GWJBkNCABpqIDcXSU3HfzmqZlfyljc0I4TWieqLNdKcM08/+IIYD6WJb+RbjOtPP4VZavkE1
//! deaJWs4R3rPFcDy9kRxoeIP9ixA2NKCBJmJDsfR1zwXmiUJiOOAlonqiy/Zaw/SzP2wxHJsmTfKo
//! EkSdLX6D6edws+0PwK31/rigQzvjZznyeOEVW4QfrxEIGhrQQBOwoVh6szX0iOGAV4jqiTbulElf
//! phiOqudnkQUNT5jiNzLzWnpYCfxg23yQW+v9c3kncxY0MRzwgu1iB68RCBoa0EATsKFY+sswjC4Q
//! wwGv0ICMNtP0O9nf/jLFcCiR0JYHp3pXDCLJFr/R5uwu3hQCX9guUOdk8zHdT/d0Nw8TzSCGAy6z
//! Dbz162a+SAKkI85sQCOxoVgwXPo98xtHYjjgBaJ6osv2GkP2t7/aFhUZp6DrNm70sBpEEfEb0WaL
//! 3yCiyX+2RsnczTSh4R7bwNvMa07zqBLAOTSggUZiQ7FgsE2hj5nzvkeVIKqI6ok2U3OBzQfTg3EK
//! WiKGA64ifiPabPEbnCP8d5klhmPMSmI44B6yxhFGNKCBRmJDseDIz00+jV4bZwoa7iKqJ7pKyzcY
//! mwtMtqUH22aExHDALcRvRJvt/Sd3U6YHWwzHdjqEcIltiIXNBxFUNKCBRmBDsWCZUGSeRmczQriF
//! qJ5os91azYXK9JHVqVPSNWI44BbiN6LNdo7gbsr0kZ+VaVwnhgNuYIgFYUUDGmgENhQLluK+nY05
//! u2xGCLcQ1RNdtulnLj6kl/Y332RcJ4YDbiB+I9qI3wiOyceZfxclH3/mUSWIEobrEVY0oIFGYEOx
//! 4LHl7BLDATcQ1RNdTLYFiy2GY9OUuzyqBFFB/Ea0cWt9sFzQwZwDvbU+7lEliIqR0981rvMagSCj
//! AQ2kyNaoZEOx9GS7RYkYDjiNqJ7osk0/s/lgejLFcCSqqpiChqOI34i2597j1vqgscVwjP2IzQjh
//! nHc+Mce68BqBIKMBDaRo7NxlxnVOBsFEDAecRlRPdNl+92w+mJ5sMRxMQcNJxG9EW5x76wPHFsPx
//! 9EZyoOEM2x0SQNDRgAZSUFq+QTV1yW+xItMzveXnmn8/xHDASab4DYSb6XfP9HP6altUpLxLLk66
//! nqiq8rAahFll6SrjOvEb4Ub8RjBd0KGdMWqRawpwim3zQV4jEHQ0oIEUsKFYsE0oMv9+xr1gnm4H
//! UmW7mMHFqvCy/e6Zfk5vHSdMMK4Tw4Hm2la+RduXbDYeQ/xGuNmaS9xNmb4u72TOgiaGA06wXczg
//! NQJBRwMaSIFtopGptvRW3LezWrVInt9WXRtnChqOYAO66LL97jlPpL/MvLyka8RwoLls2c/Eb4Sf
//! qbnEZubp7Z7u5snTGcRwoJm4QwJRQAMaaCZOBsEw5Xw2I4S72IAuumy/eybfg+GI8b9KukYMB5rL
//! lP0sEb8RdrbmEpuZpz9b42TuZprQaDrukEAU0IAGLGxvGDkZBIOt8cdmhGguNqCLLmKawqFtUZFx
//! nRgONNW28i3G9dzCDsRvhNyzNJcC7zJLDMeYlcRwoOnIEkcU0IAGLGxXIxEcts0IgeYgqie62Hww
//! PIjhgBts8Rvtio/zphD4whbzlpPNR/IgsMVwbKeDiCYifgNRwdkOMCgt32C8Gslt1cFi24yQHGi4
//! hdeK8GLzwXAhhgNuMMVvkP0cftwhFR75Wcn3lJGI4UDTcIcEooIGNGDAbdXhYptCHPfCMo8qQdjY
//! mpC8VoSXafNBpp+DhxgOOM0Wv0H2c/hxh1R4TD7O/Lsq+fgzjypBWNimn4EwoQENGJjeMGZn8IYx
//! iEwxHNW1caag0SRj55ovXvBaEU62zQeZagsmYjjgJFv8BtnP4WZrLhG/ESwXdDDnQG+tj3tUCcLC
//! FvdJ/AbChDMekITtDeO9F53sUSVwki2GY+IC89Q7cKDS8g2qqUv+gYP4jfCy3SXDhYdgssVwMAWN
//! xiB+I9pst9ZzoTJ4iOGAk2zR4cRvIExoQANJPPee+Q0jjYVgsv3eqqrNt0kCByKqJ7pMd8lw4SG4
//! 2hYVMQUNRxC/EW2p3FXH54ngIYYDTrENvPXrZp64B4KGBjSQRNxwOZLGQrCZYjgkNiNE45DtGE3k
//! focbmxHCCcRvRJvtAjW31gcTMRxwii1+Y+Y1p3lUCeANGtBAA2gshBsxHHCK7bWCD5fhZdp8UOLC
//! Q9CxGSGcQPxGtNkuUHNrfXC1yjS3UcZ+ZG4sApI9fgMIGxrQQAPI9Qy34r6d1apF8vw2YjiQKlsT
//! kg+X4WTbfJC7ZMKBGA40B/Eb0Wa7QM3mg8H2m+OPNK4/vZEcaJj96o2PjA1ohlgQRpz5gAaQ6xl+
//! U843NwaJ4UAqaEJGk+3CA3fJhAMxHGiOr178xLhO/Ea42c4TbD4YbBd0aKeYYZ3JVtj88c01xr9D
//! DLEgjGhAAwewbQZAYyEcbFPsxHDAhqieaLJNP+dkZ3CXTEjYYjg2TZrkUSUImm3lWxTfXpd0nfiN
//! 8DOdJyTupgyDyzuZs6CJ4YBJvNr8GgGEEQ1o4AC2zQB4wxgeGYbLzsRwwIaonmhiqi1aTDEcVc/P
//! IgsaDbJNPxO/EW7Eb0TDPd3NEQkziOFAEnM3VypxSMNxkAkRv4Hw4uwH7KO0fIPxliluqQ+XS79n
//! PrkTwwETU1QPHy7Dienn6DHFcCiR0JYHp3pXDALDNP2cW9iB+I2Q40JldNje7c3dTBMaB7v1489U
//! d9yhShwwDZWQFM/PJn4DocUnZGAftolGbqkPF9vJnRgOJGO7OMGHy3CiqRA9bYuKjFPQdRs3elgN
//! gsC2+WC74uM8qgR+IX4jOi6zxHCUfPyZR5UgSLbVxxXv1Eq1vdoqfkjmrsbzIZmq7Z2nuv/HBUqE
//! Fw1oYB+micbsDN4whlF+bvKpdmI4kIytEclrRfgw/RxdxiloiRgO7McUvxHLafiWa4SH7QI1d1OG
//! iy2GY2t93KNKEBT7TsXHO7XSzv4dVHN2Z+3s30HxTq2s2eJAkNGABlJ070Un+10CXDChyDzVTgwH
//! GmJqRPLhMpzuXfSRcZ3p5/CybUZIDAf2ZYrfyBtyrIeVwA+2C9TcTRk++VnmC0vEcGBft1qm4m0X
//! NYAgowEN/EtJKRONUWT7vRLDgQPZLkrw4TKcNlRVJ11j+jn8sjp1SrpGDAd2s8VvkP0cfsRvRM/k
//! 48y/U2I4sK8W0uWFAAAgAElEQVRthqn43FjSJSAUaEAD/zJzyTq/S4BPMgwne2I4cCBbVjwfLsPJ
//! 9JmA6efwa3/zTcZ1YjggSVXzViVdI34j/GzDLKMKmWwMows6mCMTiOHAbmM/Mvcb7u3BawTCjQY0
//! oF0TjQnDOrfUh9ul3zOf7InhwL5MWfE52ZxWU7V+/XpdeOGFatu2rdq0aaNhw4Zp3brULgTu2LFD
//! Y8aMUceOHZWTk6PTTjtNf/nLX1yr1XaO4KJD+BHDAZtt5VuU2Jm80UT8Rvg99575HGbb/BrB1SrT
//! /P7P1nhENDyz0RzHYruYAQQdn5QB2ScauaU+3GwfCMa9sMyjSpDubBcjmIRNzfbt2zVw4ECtXLlS
//! M2bM0DPPPKNVq1ZpwIAB2rZtm/X7r776ak2fPl133HGHFi5cqI4dO+rss8/W+++/70q9tkxPRAMx
//! HDD5etFa4zrxG40TpIuUu8VNVyoRar85/kjj+tOWxiOiwTQLT/wGooAGNFwRtDeNponG7Aym26Ig
//! Pzf5lHt1bZwpaEiSxs41X4zgtSI106dP1+rVq1VaWqri4mINHTpUCxYs0KeffqrHHnvM+L1Lly7V
//! c889pwcffFDXXHONzjrrLM2ePVtHH320br/9dsdrLS3fwKaTkEQMB8zqq2qSrhG/0ThBu0gpEb8R
//! dRd0aGeM6uLaBIjfAGhAwwVBfNNocu9FJ/vy58JbE4rMU+5sRojS8g2qqTPcXk0jMmULFixQYWGh
//! jj127y3pXbt2Vb9+/TR//nzr92ZnZ2vEiBF7HsvKytLFF1+sRYsWqaYmeROoKe5d9JFxnTtkosMW
//! w7Fpyl0eVYJ0Y9t8kPiNxgnSRcrdnrXsJUP8Rvhd3skcn0AMR7TZpuCJ30AU0ICG44L2ptE2scBE
//! YzTYfs9sRgiiepyzfPlynXjiiQc93qtXL61YscL6vV27dlVubu5B37tz50794x//cLTWjVXVSddy
//! sjM4R0SMKYYjUVXFFHREEb/hrCBdpJTs8VzcWR8N93Q3T7DOIIYjsuZurjROwedbMsSBsOBvOhwX
//! tDeNMy0TC4gOUwwHYIrqkbhY1RiVlZXKz88/6PF27dpp69atTf7e3etO6pSXk3SNzO/oscVwMAUd
//! Tab4jcy8lh5WEg5Bukgp2fcJGEn8RmTYmitzN9OEjqKSVeaLVJMtGeJAWNCAhuOC9KaxtHyD8Wok
//! t9RHiy2GgxxoJEO2Y3qbNm2aCgoKVFBQoC+++KJR3zvm7O7Kyd4/vzWmXb9zLjpET9uiIuVdcnHS
//! 9URVlYfVIB3Y4jfanN3Fm0JCJEgXKSUZ9wmQiN+IksssMRwlH3/mUSVIJ1vrzK8RxG8gKmhAw3FB
//! etNItif2ZWsmjXvBvAEdwst28YEPl42Tn5/f4Pkg2Tkg1e+V9p4v9nXttdeqrKxMZWVlOvzwwxtV
//! a3Hfzrp7WG91zstRTFLnvBw9OOJkfucR1nHCBOM6MRzR8tWLnxjXid8IhuZcqDThAnW02GI4ttYn
//! 30sE4WSbeid+A1HC33YEXnPeMJqyPbMzuKU+ikwxHNW1caagI2rsXC4+OKlXr15avvzgTO0VK1bo
//! hBNOsH7vmjVrtH379oO+t0WLFvvFPzmluG9nvXPbQK35z8F657aBnBugzLy8pGvEcETHtvItim+v
//! S7pO/EbTeH2RUmrehUpTxjMXK6MnPyvTuE4MR7Tcapl6J34DUUIDGo4L0mSbKdvz3otObtTPQjjY
//! YjgmLjBvRIfwKS3foJq65BMrRPU03pAhQ7RkyRKtXr16z2Nr167VO++8oyFDhhi/t6ioSLW1tZoz
//! Z86ex+rq6jRr1iz96Ec/UsuWNHzgviPG/yrpGjEc0WGbfiZ+o2mCdpEyWcYz08/RNPm4vReps5ZX
//! quWiDXu+spZXEsMRIXM3V2qbZeqd+A1ECQ1oOC5IbxrJ9sSBbL/3qmrzRnQIn0kvmi86ENXTeNdc
//! c426dOmioUOHav78+VqwYIGGDh2qo446Stddd92e4z799FNlZWXpjjvu2PNY3759NWLECN100016
//! /PHH9dprr+niiy/WmjVrNGnSJD/+cxBBbYuKjOub+LsYCabp59zCDsRvNFHQLlJOLu6tUYVHKzO2
//! axY6MxbTqMKjmX6OqN0Nxazllcr8rFoxac9X5mfV+mbZl36WBw/ZNh+8wpIZDoQNDWg4LkhvGsn2
//! RENMMRwSmxFGzdbt5osOXKxqvFatWmnx4sU6/vjjddlll2nkyJHq2rWrFi9erNatW+85LpFIqL6+
//! XvH4/tMjTz75pK666iqVlJRo8ODBWr9+vV5++WWdcsopXv+nIMJMMRxVz88iCzrkbJsPtis+zqNK
//! wieIFyknF/fWJ3efq7X/OVif3H0unyUirlVmxp7m8752N6ERDbbNB22Z4UDY0ICG44L2ppFsTxyI
//! GA7sZrvYwO21TXf00Udr7ty5+vrrr/XNN9+otLRUXbp02e+YLl26KJFIaOLEifs9npOTowceeECb
//! N2/Wjh079N577+nMM8/0rHZAMsdwKJHQlgenelcMPGeK34jlmDNgYcZFSgTdbwy5vjFJJaUfeFcM
//! fMHmg8DB+FsPx/GmEUFX3LezWrVI/uGRGI7osMVvMOEERFfboiLjFHTdxo0eVgOvmeI38oY4nzMc
//! NVykRJBd0KGdcXPKZ5es86wW+MMWv8Hmg4giGtBwBW8aEXRTzjc3FonhiAZT/AabDwIwTkFLxHCE
//! lC1+g+xnAKYGtMRnibCzxW+w+SCiiAY0ADTAFsVCDEf42T4YsPkgANtmhMRwhBPxGwBsRlpi2sa9
//! sMyjSuA1W/wGmw8iqmhAA0ATEMMRfrb4DfLiAUhSVqdOSdeI4Qgn4jcA2Nhi2qpr48Z1BNetH39m
//! XGfzQUQVDWgASCI/1xyxwK1z4WaK37DdVgkgOtrffJNxnRiOcCF+A0CqTHvKSHyWCKtt9ckvLvAZ
//! AlFGAxoAkphQZI5Y4Na58LJ9ILDdVgkgOojhiBbiNwCkyranDJ8lwscWv3E58RuIMBrQAJBEcd/O
//! xsmF6to4kwshNX7eB8Z1222VAKKFGI7oIH4DQKpscW3EcIQP8RtAcjSgAcDANrnAZoThU1q+Qdt2
//! Jt+5Oi/HHM0CIHqI4YiGytJVxnXiNwAcyBbpV1JqHnpAsJjiN3LJ30DE0YAGAAPb5AKbEYaPbfPB
//! iUPM0SwAoscWw7Fpyl0eVQK3bCvfou1LNiddJ34DQENskX7PLlnnUSVw29iPzL/Le3sw/YxoowEN
//! ABa2yQWEi2nzQcl+UQJANJliOBJVVUxBB9zXi9Ya14nfANAQ3jdGx9MbzfnPF3Qg/xnRRgMaACxs
//! kwvkQEcH8RsAkrHFcDAFHWz1VTVJ12I5mcRvAEhqlGXzamI4gm/u5kolDOvEbwA0oAHAyja5wA7W
//! 4WG7mED8BoBk2hYVKe+Si5OuJ6qqPKwGTtpWvsW4zvQzABPb5tXEcARfySrzZwjiNwAa0ACQElMM
//! R3VtnCnokBg713wxgdsoAZh0nDDBuE4MRzB99eInxnWmnwHYtGphzonns0Swba1LvoG5RPwGINGA
//! BoCU2GI4Ji4wb1yH9FdavkE1dcl3riZ+A0AqMvPykq4RwxFM8e11Sdcy81p6WAmAoJpyvnkKmjsq
//! g2vuZnP2c34mbTdAogENACmxTb5WVZs3rkP6m/Si+SIC8RsAUnHE+F8lXSOGI3hs8Rttzu7iTSEA
//! As32WaK6NvkQBNKbLX5j8vFHelQJkN5oQANAikwxHBK3zgXd1u3miwjEbwBIRduiIuP6pkmTPKoE
//! TjDGb2THiN8AkDJbDAebEQYT8RtAamhAA0CKiOEIL9vFA9vu5QCwL1MMR9Xzs8iCDhBT/Eb+sOM9
//! rARA0NliOGayGWHgEL8BpI7/GwAgRcV9OxsnF4jhCC5b/IZt93IA2JcphkOJhLY8ONW7YtBktvgN
//! pp8BNIbtbrqER3XAOcRvAKmjAQ0AjWCbXCCGI5hM8RtsPgigsdoWFRmnoOs2bvSwGjSVKX4jlmO+
//! lR4AGmK7q44YjmAhfgNIHQ1oAGgE2+QCMRzBY7towOaDAJrCOAUtEcMRAKb4jbwhx3pYCYCwsN1V
//! 9ywxHIFhi9+4ohPNZ2BfNKABoJEyYsnXiOEIHlv8BpsPAmgK22aExHCkN+I3ALjF9FlC4o7KoLj1
//! 48+M6/d0Zw8ZYF80oAGgkS79nvnNBG8ag8UUv2H5fAAARlmdOiVdI4YjvRG/AcAtts8S415Y5lEl
//! aI5t9fGka3yGAA5GAxoAGsl26xxvGoPDdrFgpCWnDwBM2t98k3GdGI70RfwGALfYPktU1yZvbCI9
//! jP3IHJVyOfEbwEFoQANAE+TnJt+YjjeNwTF+nnmjF9sHBAAwIYYjmCpLVxnXid8A0FytWpjvpOCO
//! yvT2zEZz/jPxG8DBaEADQBNMKDJvTMebxmDYtjP5ztV5OckvMgBAqojhCJZt5Vu0fcnmpOvEbwBw
//! wpTzuaMyyEzjRrnkbwANogENAE1g25hu4gLzxnbwn+0iwcQh5osMAJAKYjiC5etFa43rxG8AcILt
//! swR3VKYvW/zGvT2YfgYaQgMaAJrIdOtcVXXyje2QHmzxG7YPBgCQClsMx6Ypd3lUCVJRX1WTdC2W
//! k0n8BgDHmCL9JKmk1PxeFf542hK/cUEH8p+BhtCABoAmst06x5vG9FVavsEYv5GTzekRgHNMMRyJ
//! qiqmoNPEtvItxnWmnwE4yRbp9+wS86QtvDd3c6UShvX8TD5DAMnwfwcANJFtQpY3jelr0ovmiJS7
//! h/XxqBIAUWCL4WAKOj3Y4jeYfgbgJO62C56SVeYIv8nHH+lRJUDw0IAGgGaw3TrHZoTpaet2c0QK
//! HwgAOKltUZHyLrk46XqiqsrDapCMKX4jM6+lh5UAiIpRhea8YD5LpJetdcnvoJSI3wBMaEADQDPY
//! bp1jM8L0Y3sjn5djvqgAAE3RccIE4zoxHP6yxW+0ObuLN4UAiJTJxeZIv3EvLPOoEtjM3WzOfiZ+
//! AzDj/xAAaIbivp3VMiv5SymbEaYfW/zGxCHmiwoA0FSZeXlJ17Y8ONXDSnAg4jcA+CVmWKuujXtW
//! B8yI3wCahwY0ADTTPReY84K5dS69mOI3crIziN8A4Jojxv8q6Vrdxo0eVoIDEb8BwC8jLTEcbGye
//! HojfAJqHBjQANJOtYUkMR/qwXQxg80EAbmpbVCTFks+6EcPhD+I3APjJFsPBxub+I34DaD7+LwEA
//! lxHDkT5s8RtMPwNwXSKRdGnTlLs8LAS7ffXiJ8Z14jcAuM0UwyFxR6XfiN8Amo8GNAA4ID/XvHEd
//! bxrTgyl+w/bGHwCckNWpU9K1RFUVU9A+iG+vS7pG/AYAL9hiOLij0l/EbwDNRwMaABwwoci8cd2Y
//! Oe97VAmSseXn2d74A4AT2t98k3GdKWhvVZauMq4TvwHAC7YYDu6o9I8tfuOKTjSfgVTQgAYABxT3
//! 7axWLTKTrtfGmYL220xLfp7tjT8AOKFtUZHyLrk46XqiqsrDaqJtW/kWbV+yOfkB2THiNwB4xvRZ
//! QuKzhF9u/fgz4/o93RliAVJBAxoAHDLlfHMDk1vn/FNavkHJU1elvBxzhAoAOKnjhAnGdWI4vPH1
//! orXG9fxhx3tTCADI/lli3AvLPKoE+9pWH0+6RoQfkDoa0ADgkOK+nY1vQrh1zj+2zQcnDjFHqACA
//! 0zLz8pKuEcPhjfqqmqRrsZxMpp8BeMq2GXZ1bfJGKNwx9iPzHZSXE78BpIwGNAA4yJYjzK1z/jBt
//! PpidYX/DDwBOO2L8r5KuEcPhvm3lW4zreUOO9agSANjLFsNh29MEznpmozn/mfgNIHU0oAHAQbYc
//! YWI4vGdr+t970ckeVQIAe7UtKjKuE8PhLlv8BtPPAPxgi+F41rKnCZxlmjnPJX8DaBQa0ADgIWI4
//! vGeL32D6GYBfiOHwjyl+IzOvpYeVAMBevC9NH7b4jXt7MP0MNAYNaABwWH6ueUM7bp3zlil+g8EF
//! AH4ihsMftviNNmd38aYQAGjAKEukH58lvPG0JX7jgg7kPwONQQMaABw2oci8oR23znnH9gbdltkN
//! AG6yxXBsmjTJo0qihfgNAOnMFunHZwn3zd1cqYRhPT+TVhrQWPxfAwAOK+7b2bqBCJsRemOm5Q26
//! 7Q0+ALjNFMNR9fwssqBdQPwGgHTHZwl/lawyP7+Tjz/So0qA8KABDQAusG0gwmaE7ist32CcXMjL
//! MUelAIAXTDEcSiS05cGp3hUTAcRvAAgC22eJcS8s86iSaNpaV2dcJ34DaDwa0ADgguK+ndUyK/lL
//! LJsRum/8PHP8xsQh5qgUuCcej+vuu+9Wly5ddMghh+ikk07S3LlzU/reK6+8UrFY7KCvm266yeWq
//! AXe0LSoyTkHXbdzoYTXhR/wGgCCwbUZYXRv3qJLo+Y/yv8g0xUL8BtA0/J8DAC6554I+xnVunXPX
//! tp31SdeyM9hl3E+//vWvNXHiRN1444367//+bxUWFuqiiy7SSy+9lNL3H3744Xr33Xf3+7r55ptd
//! rhpwj3EKWiKGw0HEbwAICmI4/DF3aysplnyrcuI3gKahAQ0ALrE1OLl1zj22N+T3XnSyR5XgQFu2
//! bNF9992n2267TbfccosGDBigxx57TAMGDNBtt92W0s9o0aKFCgsL9/v6zne+43LlgHtsmxESw+EM
//! 4jeCgztlgP1jOIZkvK3/a3Gt1rS8VGtaXqq/t7xWb897xMfqwqli5e2KG9pkuTHiN4CmogENx/GG
//! EdgrI/nFc1XXxplccMnYuebmPtPP/lm0aJF27typUaNG7ff4qFGj9MEHH2jNmjU+VQb4K6tTp6Rr
//! xHA4g/iN4OBOGWDv+9UhGW/r3uzH9G8Z3yoW2zWc2y72rX4Te0haNtvnKsNl48aZylCSeJNEQvf2
//! ONrbgoAQoQENx/GGEdjr0u+Z36SwGaHzSss3qKYueS5eTjanPj8tX75cLVu21LHHHrvf47167crk
//! XrFihfVnbNmyRYcddpiysrJ0/PHH65577lF9ffLIFSAI2t9svthODEfzEb8RDNwpA+w1qvBo3Zo1
//! Wy1jB7/PyYhJKr3B+6JCatPm+ZKkgVokJQ4IgU4k1EvvM/0MNEOW3wUgXA58wyhJAwYM0D/+8Q/d
//! dtttOvfcc60/Y/cbRiAMJhf31rNL1iVdZzNC59k2H7x7mDmbG+6qrKxUXl6eYgdk67Vr127PusnJ
//! J5+sU089Vb169dKOHTs0b948jRs3TqtWrdLjjz/uWt2A29oWFWnjmFuTrm+acpc1qgPJEb8RHKY7
//! Zf793/9da9asUdeuXX2qDvDW5OLeipd/mfyA+E7vigm5iopxkqSr9IQkaXHibMWVoQzFNVCLdJWe
//! lHSVjxUCwcYYGBzFrdXAwfJzs43rJaXmhilSV1q+wbj5oET8htNeffXVBqOTDvw688wzHfnzbrrp
//! Jv3Hf/yHBg4cqHPPPVfTp0/XL37xCz3xxBNatWpVg98zbdo0FRQUqKCgQF988YUjdQBuMMVwJKqq
//! mIJuhq9e/MS4TvxG+uBOGWB/GxOHmQ+YMcSbQkIukdh7l8xVekLPaLhm6kI9o+G6Sk/ohBPu87E6
//! IPhoQMNRvGEEDjahqJdxfaZhQhqNM+lFc6TJqEJy25x2+umnq6Kiwvr19NNPS5Ly8/NVVVWlxAG3
//! Nu6efN49Cd0Yl1xyiSSprKyswfVrr71WZWVlKisr0+GHH97onw94xRbDsWnKXR5VEi7byrcovr0u
//! 6TrxG+nFiTtl7r//fs2ePVsLFixQ//79NW7cOF133XWu1Qy46a9dfnZQIsR+1rzpWS1h9X9/v8x6
//! TMcOQz2oBAgvIjjgKG6tBg5W3Lezxs/7IOlkrun9JBpn63ZzpMnk4t7GdTRebm6uevTokfLxvXr1
//! Uk1NjT755JP9LlbuvkB5wgknNLmWA889QNC0LSrS9r//XVV/fL7B9URVlccVhUPVvIbvjtiN+A13
//! vfrqqxo0aJD1uP79++uNN95o9p934Obl5557rlq3bq2pU6dq7NixOu644w76nmnTpmnatGmSxJ0y
//! SDvD//2XSky8w3zQwtHSeQ94U1AIVVX91bjeqdNIjyoBwosJaBhxazXgjCnnmxufxHA0X2n5BuN6
//! Xo45CgXeOOecc5Sdna2ZM2fu9/izzz6rE088sUm5njNnzlQsFtN3v/tdp8oEfNNxwgTjOjEcjbOt
//! fIsSO5NvTJtb2IH4DZdxpwzQfLFMy50aZU94U0gIVay83XpMzx6WCwAArJiAhtHuN4w2ubm5kvZ/
//! w7jvJFpz3zBOnTpVZWVlDU4sXHvttbr22mslSQUFBY3++YAXivt21k2z3k+6/uySdUznNpMtfmPi
//! EHMUCrzRvn17jR49WnfffbcOPfRQnXLKKZo1a5YWL16sBQsW7HfsWWedpU8//VT/+Mc/JEmffvqp
//! LrvsMl188cU69thjVVNTo3nz5umpp57Sddddp27duvnxnwQ4LjMvT/VJpp3ZjLBxvl601rjervjg
//! 95ZwFnfKAA4Y+pD0wjXmY5bNlvoM96aeENm4caZxPS/vdI8qAcKNBjSMeMMIOCc/N9sYEVFavoEN
//! 8prBFr/Bc5s+pkyZotatW+u3v/2tNm/erO7du2v27Nk677zz9juuvr5edXV7c1sPPfRQtWvXTvfc
//! c48+//xzZWRkqEePHvrd736nn/3sZ17/ZwCuOWL8r7RxzK0NrhHD0Tj1VTVJ12I5mR5WglTte6fM
//! hH3uCOBOGURan+FS6fVSPHmevUpvoAHdSJs2z7cec+opz3hQCRB+NKDhKN4wAslNKOplnIIeM+d9
//! mqRNZIswIX4jvWRmZqqkpEQlJSXG4w7MAm3Xrp1KS0tdrAxID22LipI2oKVdMRxMQacmM69l0iZ0
//! 3pBjG3wc/uJOGSCJ4kfNU9Dxnd7VEhIVFeMsR5BaCziFBjQcxRtGILnivp01du4y1dQ1nEVZG2cK
//! uqlmLllnXCd+A0DQEMPhjIrt/6tj4icoK2PvhchEIqGtbf6pI/ue4WNlMOFOGaABfYbbYzge+p50
//! 43ve1BMCiUTyu2Qk6YQT7vOoEiD8aEDDcbxhBJK754I+xinocS8sowHdSKXlG5QwrOdkZ/CcAggc
//! Yjiar+Kt11X+0cv6Z6tP1Se/v3Kz2mh73ddatvVNrft0pfrofL9LRBLcKQMk0bW/tObN5OtfrvSu
//! loD767vnWI/p2GGoB5UA0UADGo7jDSOQXHHfzrp51vtJG6bVtQ1PRyM52+aDdw/r41ElAOAcWwzH
//! pkmT1HGfuDMcbNFjv5MkrdtWoXXb7JtqA0Dau2KBNLGt+ZiFo6XzHvCmngCrrl5lXO/UaaRHlQDR
//! QKANAHhsZOHRxvXS8g0eVRIObD4IIKwy8/KSrlU9P0tfvfiih9UEy6uPP6L6WvP5AQACqWt/83rZ
//! E97UEWAVK2+3HtOzxx0eVAJEBw1oAPDY5OLexvUxc5JHdGB/bD4IIMyOGP+r5IuJhLY8ONW7YgKk
//! 4q3XtfSVl4zHZLZs6VE1AOCwKxbYj1k42v06AmzjxpnG9by80z2qBIgOGtAA4INWLTKTru3ejBB2
//! z7L5IIAQa1tUZJyCrtu40cNqguPlR+2N+bOvudGDSgDAJZmWi2hMQSe1afN86zGnnvKMB5UA0UID
//! GgB8MOV88xT0uBeWeVRJcNmmn9l8EEAYGKegJWI4DjD7zvGK19cbjznqxJPU84wBHlUEAC4Y+pDf
//! FQRWRUXy/RV24Q5KwA00oAHAB8V9OytmWGczQruZlulnNh8EEAZti4qM68Rw7FXx1uta/+FS4zGx
//! zEwN//UUjyoCAJf0GW4/ZsYQ9+sImE2b5yuRqDMec8IJ93hUDRAtNKABwCe2zQhtE75RVlq+QQnD
//! enYGmw8CCI+sTp2SrhHDsdeix35nPebH19/kQSUA4IGCq83ra970po4AqagYZz2mY4ehHlQCRA8N
//! aADwiW0zQlu+cZSNn2duzt970ckeVQIA7mt/s7lpSgyH9Orjj6i+ttZ4DNEbAELlvAfsxzAFvZ9E
//! osa43qnTSI8qAaKHBjQA+Mi0GaHEFHRDSss3aNtOc74n088AwsQWw7Fpyl0eVZKeKt56XUtfecl8
//! UCxG9AaA8Ona37zOFPQe//f3y6zH9OxxhweVANFEAxoAfGTbjJAp6IPZpp/zctg4BED4mGI4ElVV
//! kZ6CfvlRew72uTeM9qASAPDYFQvsxyzk9U+Sqqr+alzPyzvdo0qAaKIBDQA+Ku7bWS2zzC/FTEHv
//! lcr088QhvTyqBgC8Y4vhiOoU9Ow7xytebz4vEL0BINQO62FeL3vCmzrS2KbN863HnHrKMx5UAkQX
//! DWgA8Nk9F/QxrjMFvdekF5cb13OyM4jfABBKbYuKlHfJxUnXE1VVHlaTHireel3rP1xqPCaWmUn0
//! BoBwu/E9+zHLZrtfRxqrqLjVuM70M+A+GtAA4LNUpqBLyzd4VE1627rdvMHU3cPMzXwACLKOEyYY
//! 16MWw7Hosd9Zj/nx9ebJcQAIhcyW5vUXfupNHWlo0+b5SiTqjMcw/Qy4jwY0AKQB2xT0uBeWeVRJ
//! +rI14Zl+BhAFmXl5SdeiFMPx6uOPqL7WfFGS6A0AkTH0IcsB9ZGdgq6oGOd3CQBEAxoA0oKtcVpd
//! G4/8FPQtc8y3WTP9DCAKjhj/q6RrUYnhqHjrdS195SXzQbEY0RsAoqPPcPsxpTe4X0caSiRqjOud
//! Oo30qBIg2mhAA0CayM/NNq6PmfO+R5Wkn5LSD1QXTxiPYfoZQBS0LSoyrkchhuPlR6dajzn3htEe
//! VAIAaaTgavN6fKc3daSR//v7ZdZjeva4w4NKANCABoA0MaGol3G9Nh7dLGjbRoyjCo/2qBIA8F+U
//! Yzhm3zle8fp64zFEbwCIpPMesB+zMFoX57Zu/atxnc0HAe/QgAaANFHct7Natcg0HhPFKeiS0g+s
//! x0wu7k0SELIAABmRSURBVO1BJQCQHqIaw1Hx1uta/6E5jimWmUn0BoDo6tp/v3+d3C5PJ3U5Sr27
//! HKWTuhylyavn+lSY92bMmGE9hs0HAe/QgAaANDLlfHMjNYpT0Ew/A8D+bDEcmyZN8qgSb6USvfHj
//! 62/yoBIASFNXLNjzj5Pb5WlWm0MVj8WkWEzxWEyz2hyqyX/8sY8FemfNmjVJ1xIJpp8Br9GABoA0
//! Uty3s/p1a2c8ZtwLyzyqxn+2ZnuGmH4GEE2mGI6q52eFLgua6A0ASFFmS0nSrDaHSrHY/muxmGbV
//! rPehKG/dfffd1mOYfga8RQMaANLMzGtOM65X18YjMwV9yxzzrdYPjDjZo0oAIL2YYjiUSGjLg/Zp
//! 4aBIJXpDsRjRGwAgSUMfsh5y1qyzPCjEH8uWLVNNTY0kKR6PNXhMsscBuIcGNACkIbKgd2U/18UT
//! xmOK+3b2qBoASC9ti4qMU9B1Gzd6WI27UoneOPeGaG2sBQBJ9RkuxQytnlhMW3Zs0Z9X/9m7mjz0
//! wgsv7PnnVR+frnh8//V4XKqvG+VxVQBoQANAGiILmuxnALAxTkFLoYjhIHoDAJrg/Mesh9z21m0e
//! FOKthQsX7vfvX3xxjD7+qJ927GilRELasaOV/rHqDP34xxP9KRCIMBrQAJCGivt2jvQUdEnpB9Zj
//! yH4GEHW2zQiDHsORSvRGuyOPInoDAA7UZ7gyTFPQ/zJ5yWQPivFOWVnZQY998cUx+tv/DtPbb12m
//! v/3vMF1//VPeFwaABjQApKsoT0Ez/QwAqcnq1CnpWtBjOFKJ3rjq/kc9qAQAgueuM+wb8c36aJYH
//! lXjjoYfs2deHHXaYB5UAaAgNaABIU8V9O6tft3bGY0bPCt8U9Mjp7xrXM8T0MwDs1v7mm4zrQY3h
//! ePXxR6zRGycNOtejagAgeAYfM1jtD2lvPS4sGxJ++eWX1mNuvPFGDyoB0BAa0ACQxmZec5pxPS57
//! wzZISss36J1PKo3HPDDiZI+qAYD0Z4vh2DTlLo8qcdbSV14yHxCL6Yc/+Zk3xQBAQL024jXrMWHY
//! kPDOO++0HtO1a1cPKgGQDA1oAEhztizodz6pDE0Ux/h59uzn4r6dPagEAILDFMORqKoK3BT0k7+8
//! 3nrMuTeM9qASAAi+wg6F1mOCvCHhwoULVW+5Y0aSrrjiCg+qAZAMDWgASHO2LGhJmrhguQeVuG/b
//! TvObR7KfAeBgthiOIG1GOPvO8ar8bL3xmKNOPEk9zxjgUUUAEGzTz56e0nFB3ZCwoY0HDzRs2DAP
//! KgFgQgMaANJcKlnQVdW1HlXjHrKfAaBp2hYVKe+Si/f8+99736DF/R/a8/VKtzH6+L3NPlaYmoq3
//! Xtf6D5eaD4rFNPzXU7wpCABC4j/P+E/rMUHckHDGjBnWY1q2bKk+ffp4UA0AExrQABAAM685TVkZ
//! MeMxQc6CJvsZAJqn44QJUiymv/e+QVXtekqx2J6vRGYLvfLkcj03Mb3PEy8/ap/UJnoDABpv8DGD
//! dWjWodbjiucVe1CNc9asWWM9Zty4cR5UAsCGBjQABMR9F51kXA9yFvQtc8wTb9kZZD8DgFUisbf5
//! fJCYtm6u1sM/XZyW09CvPv6I4pYMT6I3AKDp/jryr9ZjPvn6Ew8qccZ9991nPYaNB4H0QQMaAAKi
//! uG9nmWegpZtmve9JLU4aOf1d1cUTxmPuvYjpZwCwMW1GuK9XnlyRdtPQS195yXwA0RsA0GypbEhY
//! 8HSBB5U0z7Jly/Ttt99aj2PjQSB90IAGgAAZmcImfEGK4kgleoPpZwBIjW0zwn2l0zT0k7+83noM
//! 0RsA0HypbEhYk6hJ+w0JX3jhBesxBQXp30gHooQGNAAEyOTi3tYs6CBFcdiiNySmnwEgVW2LinRY
//! i61SwnxXyb78noaefed4VX623ngM0RsA4Jygb0i4cOHClI4777zzXK4EQGPQgAaAgLFlQUvS6ABE
//! caQSvdGvWzumnwGgEUb8/kId0jLRqCa0X9PQFW+9rvUfWi5EEr0BAI4K+oaEZWVl1mOGDRvmQSUA
//! GoMGNAAETHHfzjqufSvjMXGldxRHKtEbkjTzmtM8qAYAwuXq3/1QJ/Zv/MU7r6ehX350qvUYojcA
//! wHlB3ZBw6sTfSJbrq61bt1afPn28KQhAymhAA0AAvTL6TFmSONI6imP0bPuE9qgU8q4BAA3rf2kP
//! 3fCHgcptk92o7/NqGvrVxx9RvL7eeAzRGwDgngM3JPzVc3Wadff+X/97Uk+fqjvYZ+PfUlViu2y7
//! st9yyy3eFASgUWhAA0BAPTDcno18UxpGcQx64A1Zkjd0XPtWmlzc25uCACDErvrNGTrxB50a/X1u
//! T0MvfeUl8wFEbwCAq/bdkPBXz9XppE939Xb3/WpdI1X08L8J/dmEtyXzNUtJUteuXd0vBkCT0IAG
//! gIAq7ttZ/bq1sx73vSmveFBNakZOf1ertmwzHpOhXRPeAABnpNs09JO/vN56DNEbAOC+Ed1HSNKe
//! 5vOBdj/mZxP6synvSjWp7WtwxRVXuFwNgKaiAQ0AAZZKRvLn3+xMizzoVHOfHxhhn+wGADReOkxD
//! z75zvCo/W288hugNAPBGSWGJWsZapnSsH03oz6cvlb6p2/PveYmchjOgE2w8CKQ7GtAAEHCpZCW/
//! 80mlSko/8KCa5G5OIQ7kuPatVNy38RtnAQBS4+c0dMVbr2v9h0vNBxG9AQCeKru8LOVjvWxCV5au
//! Uu0nX+/32IU7T9/bhP7XVywR05mZvdl4EEhzNKABIOAmF/fWce1bWY97dsk63zYl/N6UV2wbVksi
//! egMAvOLHNPTLj061HkP0BgB4r/rkY1N6ry5504SuLF2l7UsavuB54c7T9ZOas/Z8XV0zUGfefoHr
//! NQFoHhrQABACr4w+U0cc2sJ6nB+bEg564A19/s1O63FTid4AAE95OQ396uOPKF5v3kGK6A0A8Mep
//! z7+oeIvMtGhCbyvfkrT53JAj//MM12oB4Bwa0AAQEu+NH5TScT3Gv+RyJXsNeuAN66aD0q4YEaI3
//! AMAfXkxDL33Fcu4hegMAfHXisg8Va5laHrQkVfQ8wZU6ts76KOVjaT4DwUEDGgBCJJU86B31CfWZ
//! 8LLrtaTafD6ufStNLu7tej0AgOTcnIZ+8pfXW38O0RsA4L+eS9+XDj00tYMTCVX0OtHRP/+z295K
//! +Viaz0Cw0IAGgBBJNQ/665p6VyehU20+t2mZSe5zBD3wwAMqKipSx44dFYvFNHHixEZ9/9tvv63T
//! Tz9dOTk56tChg0aPHq3q6mp3igUixulp6Nl3jlflZ+uN30v0BgCkj55/+18p1Uno+nrHJqFpPgPh
//! RgMaAELmldFnptSE3lGfUJfb/uz4xoTfm/JKSs1nSVo26RxH/2wEw/Tp07VlyxYVFxc3+nuXLVum
//! QYMGqX379lq4cKEmT56sJ598UldeeaXzhQIR5dQ0dMVbr2v9h0vN30T0BhrAhUrAXz2Xvi9lZiZd
//! X/z9+7S4/0O7vn7wez38k6YPttw/4jx9euvrSiRSS6Cm+QwEU5bfBQAAnPfK6DPVZ8LL+rrGvOGT
//! tGtjwrJPKx2Jwegx/iXtqE/tzSObDkbX8uXLlZGRobq6Ov3hD39o1PdOmDBBRx55pObMmaPs7F3N
//! sRYtWuiKK67Q2LFjdcopp7hRMhBJV/3mDL353Ep9+JeNjfq+V55cobL/XqPPP55qPZboDTRk+vTp
//! atOmjYqLixt9nth9ofLss8/WwoULtWbNGo0ZM0YbNmzQrFmzXKoYCJ+eyz/cFbFxwAayi79/n5R5
//! iBSL7X0ws6Uevu61PY/d8IeBxp89ddQw1dfu2qT86FY9lRHLVGzfn5cEzWcguJiAhuOYWADSw7JJ
//! 5+iQTPsbOUl6dsk6DXrgjSb/WSWlH6jLbX9Oufncr1s7Nh2MsIyMpr39qK2t1csvv6zhw4fvaT5L
//! 0vDhw9WiRQvNnz/fqRIB/EtTp6E3/+NFxevNF0GJ3kAyy5cv13vvvaff//73jf7efS9UnnXWWfrJ
//! T36i3/72t5o9e7b+/ve/u1AtEF49l3+4f6NZOrj5LO36930ee/ini/d87b4r5slfXq/7R5yn+0ec
//! t6f5LEl98vvTfAYigAY0HMet1UD6WDnlXLVpmfz2uX2t2rJNXW77s0ZOPzjDM5nS8g3qctuf9eyS
//! dSl/T79u7TTzmtNSPh7Y7ZNPPtGOHTt04on7b3hzyCGHqFu3blqxYoVPlQHh19hs6ETtMvMBRG/A
//! gAuVQProWdH091d1NRV68YGf6P4R5yXdDyA3q43159B8BoKPCA44jlurgfSybNI5jYrGeOeTSnW5
//! 7c/KyojpvotOanBSOdVNBg9E8xnNUVlZKUnKz88/aK1du3Z71gG4o/+lPdT/0h568ta3tP3r2qTH
//! 1Xz7qvVnEb0BN3ChEnBHz5UVqujRs1HfU1dTobrt/209bnvd12qV3Tbpev6I7o36cwGkJyag4Tgm
//! FoD0s3LKuSnHcexWF0/oplnvq8ttfz7oi+Yzdnv11VcVi8WsX2eeeaZvNU6bNk0FBQUqKCjQF198
//! 4VsdQFjYpqFt089Eb8AtXKgE3NNzZcWuf6jfIaWwYWDd9v9J6ecu2/qm6uN1Bz2eSCSUW9hBrfq2
//! b1SdANITE9BIG0wsAO5aOeXclDcmdNrUESeT+RxSp59+uioqKqzH5ebmNvvP2t1Q2Lp160FrlZWV
//! 6tWrV4Pfd+211+raa6+VJBUUFDS7DgCpT0MfhOiNyHn11Vc1aNAg63H9+/fXG2+84X5BDZg2bZqm
//! TZsmSVyoBAx6rqxQxg/669Uev971gDG7ObXPHOu27Xof2bfdD9UyM0eSVBOvVsdL+9J8BkKEBjTS
//! BhMLgPuWTTpH35vyij7/Zqf9YAcckhnTyinnevJnwR+5ubnq0aOHJ39Wt27d1LJlSy1fvny/x3fs
//! 2KHVq1froosu8qQOAHtd9Zsz9OZzK/XhXzamdDzRG9HDhUogXLr/5U11166NBp2yblvFvxrRMf1y
//! 1ouO/VwA6YMGNIyYWADC573xg1RS+kGjNg5siuPat9Iro8909c9AtLRo0ULnnHOOZs+erYkTJyor
//! a9fbmD/96U+qqanRkCFDfK4QiKaDp6Ez1fDkW4zojQjiQiUQTjf8YeCef25uM/qkQefqhz/5WXNL
//! ApDGaEDDiIkFIJwmF/fW5OLeTd5M0CQm6UEiN2BQVlamtWvXKh6PS5JWrFihP/3pT5Kkc889d885
//! 5eqrr9aMGTNUV7c3F3DixIkqLCzU8OHDdcMNN2jt2rUaM2aMLrzwQp166qne/8cA2GP3NPT7r/yo
//! wY2n+v74ah+qQpRwoRLwR4PN6IyjpPj6pN/TIreV/uPJWW6XBiBN0ICGERMLQLjtnlAeOf1dvfNJ
//! 82NuRhUercnFvZv9cxBuDz30kGbMmLHn3+fMmaM5c+ZIktasWaMuXbpIkurr61Vfv/8U5cknn6z/
//! +Z//0dixYzV48GC1bdtWl19+ue666y7P6geQ3O5p6MVPddbSV2YrXve1MrLa6KRBwzXwymK/y0NA
//! cKESCK69zeiBemDU9UrU7m1Cx7KP0uhnH/WnMAC+iiUSKWxfCjRBXV2dsrOzNWHCBE2cODGl7yku
//! LtaKFSu0YsWKPRMLzz77rC677DKVlZVZ3zQWFBSorKysuaUDkdWUaI5+3dpp5jWnuVQRnMLr4y48
//! DwDQsHR6fbzyyiv3u1C5r30vVO4+7sCPtH/5y180duxYlZeXq23btrrkkkt01113pXTXZjo9DwCQ
//! Tnh9RHMwAQ3HMbEABNfuaA4AAAC/PPXUU3rqqaeafNwPfvADvfvuu84XBgAAmoQGNBzHrdUAAAAA
//! AAAAJCnD7wIQPk899ZQSiUSDX7ubz/sed6DdEws7duzQ559/rqlTpzqyySEAAAAAAAAAb9GABgAA
//! AAAAAAC4ggY0AAAAAAAAAMAVNKABAAAAAAAAAK6gAQ0AAAAAAAAAcAUNaAAAAAAAAACAK2hAAwAA
//! AAAAAABcQQMaAAAAAAAAAOCKWCKRSPhdBOCUww47TF26dGnS937xxRc6/PDDnS0o4nhOncdz6ryo
//! PKdr167Vl19+6XcZvuM8kV54Tp3F8+m8KD2nnCd24TyRPng+ncdz6qyoPZ+cJ9AcNKCBfykoKFBZ
//! WZnfZYQKz6nzeE6dx3OKVPF3xXk8p87i+XQezykag78vzuL5dB7PqbN4PoHUEcEBAAAAAAAAAHAF
//! DWgAAAAAAAAAgCsyJ06cONHvIoB0ceqpp/pdQujwnDqP59R5PKdIFX9XnMdz6iyeT+fxnKIx+Pvi
//! LJ5P5/GcOovnE0gNGdAAAAAAAAAAAFcQwQEAAAAAAAAAcAUNaETa+vXrdeGFF6pt27Zq06aNhg0b
//! pnXr1vldVmD96U9/0gUXXKDvfOc7ysnJUffu3TVu3Dh98803fpcWKuecc45isZhKSkr8LiXQXnrp
//! Jf3gBz9Q69at1aZNGxUUFGjx4sV+l4U0w3nCWZwn3Mc5whmcI5AqzhPO4RzhPs4RzuAcATQeDWhE
//! 1vbt2zVw4ECtXLlSM2bM0DPPPKNVq1ZpwIAB2rZtm9/lBdJ9992nzMxM3XXXXXr55Zd1/fXX69FH
//! H9WgQYMUj8f9Li8U/vjHP2rp0qV+lxF4jz32mIYOHapTTz1V8+bN05w5c3TRRRdp+/btfpeGNMJ5
//! wnmcJ9zFOcIZnCOQKs4TzuIc4S7OEc7gHAE0UQKIqKlTpyYyMjISq1at2vPY6tWrE5mZmYn777/f
//! x8qCa8uWLQc9NmPGjISkxGuvveZDReFSWVmZOOKIIxLPPfdcQlJi/PjxfpcUSGvWrEkccsghiQcf
//! fNDvUpDmOE84j/OEezhHOINzBBqD84SzOEe4h3OEMzhHAE3HBDQia8GCBSosLNSxxx6757GuXbuq
//! X79+mj9/vo+VBdfhhx9+0GPf/e53JUkbNmzwupzQGTt2rE488URdcsklfpcSaP/1X/+ljIwM/fSn
//! P/W7FKQ5zhPO4zzhHs4RzuAcgcbgPOEszhHu4RzhDM4RQNPRgEZkLV++XCeeeOJBj/fq1UsrVqzw
//! oaJwevPNNyVJPXv29LmSYHv77bf19NNP6+GHH/a7lMB7++231aNHDz3//PPq1q2bsrKydOyxx/Lc
//! 4iCcJ7zBeaL5OEc4h3MEGoPzhPs4RzQf5wjncI4Ami7L7wIAv1RWVio/P/+gx9u1a6etW7f6UFH4
//! bNiwQbfffrt++MMfqqCgwO9yAmvnzp267rrrdMstt6h79+5+lxN4Gzdu1MaNGzVmzBjddddd6tat
//! m+bMmaMbb7xRdXV1+sUvfuF3iUgTnCfcx3mi+ThHOItzBBqD84S7OEc0H+cIZ3GOAJqOBjQAV3z7
//! 7bcaOnSosrKy9OSTT/pdTqD95je/UXV1tcaPH+93KaEQj8f1zTff6KmnntKwYcMkSQMHDtTatWt1
//! 99136+c//7lisZjPVQLhx3nCGZwjnMU5AkgPnCOcwTnCWZwjgKYjggORlZ+f3+BkQrJJBqSuurpa
//! RUVFWr16tRYtWqQjjzzS75ICa926dZoyZYruvPNO1dTUqKqqSlVVVZK059/r6+t9rjJY/u3f/k2S
//! NGjQoP0e/9GPfqTPP/9cmzZt8qMspCHOE+7hPOEMzhHO4xyBxuA84Q7OEc7gHOE8zhFA09GARmT1
//! 6tVLy5cvP+jxFStW6IQTTvChonCora3VhRdeqLKyMr300kvq3bu33yUF2urVq7Vjxw6NGjVK+fn5
//! e74k6b777lN+fr4++OADn6sMll69ehnXMzI4NWIXzhPu4DzhHM4RzuMcgcbgPOE8zhHO4RzhPM4R
//! QNPxfwcia8iQIVqyZIlWr16957G1a9fqnXfe0ZAhQ3ysLLji8bhGjhypxYsXq7S0VIWFhX6XFHgn
//! n3yyXn/99YO+JGnUqFF6/fXX99t5HXbnn3++JGnRokX7Pf7yyy/ryCOPVIcOHfwoC2mI84TzOE84
//! i3OE8zhHoDE4TziLc4SzOEc4j3ME0HSxRCKR8LsIwA/btm3TSSedpJycHE2ePFmxWEy//vWv9c03
//! 32jZsmVq3bq13yUGzvXXX68//OEPGj9+vM4777z91o488khun3NQLBbT+PHjNXnyZL9LCZxEIqGz
//! zjpLS5cu1ZQpU3TMMcdozpw5evzxx/Xkk0/qyiuv9LtEpAnOE87jPOENzhFNxzkCjcF5wlmcI7zB
//! OaLpOEcAzZAAIuzTTz9NDBs2LHHooYcmWrdunRg6dGhizZo1fpcVWN/5zncSkhr8mjBhgt/lhYqk
//! xPjx4/0uI7C++uqrxM9+9rNE+/btE9nZ2YnevXsnZs6c6XdZSEOcJ5zFecIbnCOah3MEGoPzhHM4
//! R3iDc0TzcI4AmoYJaAAAAAAAAACAK8iABgAAAAAAAAC4ggY0AAAAAAAAAMAVNKABAAAAAAAAAK6g
//! AQ0AAAAAAAAAcAUNaAAAAAAAAACAK2hAAwAAAAAAAABcQQMaAAAAAAAAAOAKGtAAAAAAAAAAAFfQ
//! gAYAAAAAAAAAuIIGNAAAAAAAAADAFTSgAQAAAAAAAACuoAENAAAAAAAAAHAFDWgAAAAAAAAAgCto
//! QAMAAAAAAAAAXEEDGgAAAAAAAPj/7dixAAAAAMAgf+tR7CuMgIWABgAAAABgIaABAAAAAFgIaAAA
//! AAAAFgIaAAAAAICFgAYAAAAAYCGgAQAAAABYCGgAAAAAABYCGgAAAACAhYAGAAAAAGAhoAEAAAAA
//! WASuc53nV8F7nQAAAABJRU5ErkJggg==
//! ">
//! </div>
//!
//! In the example above, we show the original 1000 data points (left), a
//! PLR with a maximum error of 0.05 (center), and a PLR with a maximum
//! error of 0.005. All of the displayed PLRs are optimal, meaning that
//! they contain the fewest number segments possible to achieve their error
//! bound.
//!
//! This package can perform PLR using one of two online algorithms:
//! * [Greedy PLR](regression/struct.GreedyPLR.html), which uses a constant
//!   time per point and a constant amount of space. Greedy PLR always
//!   finds a PLR with the specified error bound (e.g., none of the
//!   original points will be more than δ from their predictions), but the
//!   greedy approach may not find the PLR with the minimal number of
//!   segments.
//! * [Optimal PLR](regression/struct.OptimalPLR.html), which uses a linear
//!   time per point and potentially linear space. In practice, the amount
//!   of space used by the optimal algorithm should be small, but in the
//!   worst case linear space may be required (see [the
//!   paper](https://dl.acm.org/citation.cfm?id=2691542) for more details).
//!   The optimal algorithm will find the solution with a minimal number of
//!   segments.
//!
//! This package can also perform spline regression instead of piecewise
//! linear regression. See [greedy_splines](spline/fn.greedy_spline.html),
//! or the online version [GreedySpline](spline/struct.GreedySpline.html).
//!
//!
//! Written by [Ryan Marcus](https://rmarcus.info), licensed under the GPL
//! v3.

pub mod regression;
pub mod spline;
mod util;

#[cfg(test)]
mod test_util;

#[cfg(test)]
mod data;

//pub use regression::GreedyPLR;
//pub use regression::OptimalPLR;

pub use util::Segment;
